当前位置:   article > 正文

python中iter()函数和__iter__方法研究_通过重载深度理解__iter__函数和__next__函数(Python)...

python iter next for in

前言:

最近在学习二叉树的时候碰到个二叉搜索迭代器,是通过__iter__重载循环for x in 实现的,随即对__iter__函数的重载做了一些深度的了解,自己写了一些例子来加深理解,也希望对大家有所帮助。大家觉得有用的话,可以三连一下哈。

1、__iter__函数和__next__函数

1、__ iter__ 返回一个特殊的迭代器对象, 这个迭代器对象实现了 __ next__ 方法并通过 StopIteration 异常标识迭代的完成。

2、__next__方法(Python 2 里是 next())会返回下一个迭代器对象

下面举个例子来解释二者的用途。这是自己重写了一些range()函数。

class range_():

def __init__(self,N):

self.N = N

self.a1 =0

def __iter__(self): # 在迭代开始时运行一次,之后进入__next__

return self

def __next__(self): # 循环调用__next__

an = self.a1

if an == self.N:

raise StopIteration

else:

self.a1 += 1

return an # an作为i返回

for i in range_(3):

print(i)

这里for in 语句,触发__iter__ 函数,然后再循环调用__next__.下面去掉__iter__看会发生什么变化。

class range_():

def __init__(self,N):

self.N = N

self.a1 =0

def __next__(self):

an = self.a1

if an == self.N:

raise StopIteration

else:

self.a1 += 1

return an*3

t = range_(3)

for i in range(3):

print(t.__next__(3)) #通过外部的循环语句,来循环调用__next__函数,同样可以实现。虽然是外部循环调用__next__,但是他把a1的变化传递下去了。此时的range_可以理解为可迭代对象,但不是迭代器

##输出:

0

3

6

可以看到,再没有iter语句的情况下,通过原来的for in语句,会报错,这说明此时的对象并不属于一个迭代器,但仍然可以通过外加遍历条件通过__next__语句进行遍历,所以可认为是一个可迭代对象。同时for in语句被认为是对iter语句进行调用的触发器,在缺乏iter的情况下,也合理的会报错。

2、重载了for x in操作的__iter__函数

def __iter__(self):

if self:

if self.hasleftchild():

for elem in self.leftchild:

yield elem

yield self.key

if self.hasrightchild():

for elem in self.rightchild:

yield elem

在上面由于for elem in的存在,其实是隐藏了对iter的递归调用。所以在这里他是可以实现对二叉树的中序遍历的。这里面的yield函数就相当于return,但是会冻结状态。下面我把它放到一个已经构建好的完全二叉树中,看一下怎么用。

class BinaryTree():

def __init__(self,key,left = None, right = None):

self.key = key

self.val = None

self.left = left

self.right = right

def __iter__(self):

if self:

if self.left:

for elem in self.left:

yield elem

yield self.key

if self.right:

for elem in self.right:

yield elem

def buildtree(lst):

nodelst = [BinaryTree(i) for i in range(1,len(lst)+1)]

i = 0

for node in nodelst:

if node.key ==1:

pass

elif node.key %2 == 0:

nodelst[i].left = node

elif node.key %2 == 1:

nodelst[i].right = node

i = i +1

return nodelst[0]

# return currentTree

lst = [1,2,3,4,5,6,7,8,9,0]

Tree = buildtree(lst)

for item in Tree:

print(item)

正如前面所讲,for in 触发__iter__函数,然后实现对二叉树的中序遍历。在这里在没有__next__的情况下实现了迭代器的遍历机制。因为yield返回了迭代器对象,保存在了这个迭代器对象的容器中。

yield:生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。调用一个生成器函数,返回的是一个迭代器对象。

下面再举个例子进行上述理解的验证:

class range_():

def __init__(self,N):

self.N = N

self.a1 =0

def __iter__(self):

return iter([1,2,3,4,5])

t = range_(3)

for i in range_(3):

print(i)

原文链接:https://blog.csdn.net/weixin_42808887/article/details/106322895

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/145642
推荐阅读
相关标签
  

闽ICP备14008679号