赞
踩
前言:
最近在学习二叉树的时候碰到个二叉搜索迭代器,是通过__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
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。