Python
中有个特殊的方法__iter__()
,若对象有个这个方法,说明是可迭代的。查看对象是否可迭代用hasatrr(list, "__iter__")
list1 = [1, 2, 3, 4]
iter_list1 = iter(list1)
iter_list1 # 结果显示是迭代器对象
结果:
<list_iterator at 0x1386893e898>
hasattr(list1, "__iter__") # True
hasattr(iter_list1, "__iter__") # True
-
iter_list1
那样的对象在Python
中称之为迭代器对象。迭代器对象必然是可迭代的。Python
中迭代器对象实现的是\__next__()
方法(Python2
中是next()
)。
手写迭代器对象
class MyRange: # 定义一个类
def __init__(self, n): # 初始化函数,传入参数n;self就是一个实例对象,具有下面的各种属性
self.i = 1 # 属性i的值为1
self.n = n # 属性n的值为n
def __iter__(self): # 返回迭代器本身,一个实现了__iter__()方法的对象说明它就是可迭代的
return self
def __next__(self): # 实现__next__()方法说明对象就是迭代器对象
print("self.i", self.i)
if self.i <= self.n:
i = self.i
self.i += 1
return i
else:
raise StopIteration()
if __name__ == "__main__":
x = MyRange(7) # 建立实例化对象x,并且传入参数n=7
print([i for i in x]) # 列表的形式显示
# print(list(i for i in x)) 同上功能
结果
self.i 1
self.i 2
self.i 3
self.i 4
self.i 5
self.i 6
self.i 7
self.i 8
[1, 2, 3, 4, 5, 6, 7]
解析
-
__init__
函数实现初始化功能 - _iter_函数返回迭代器本身
- _next_函数中:
- self.i表示迭代次数变量
- 返回值是i
self.i(before) | self.n | i | self.i(after) |
---|---|---|---|
1 | 7 | 1 | 2 |
2 | 7 | 2 | 3 |
3 | 7 | 3 | 4 |
4 | 7 | 4 | 5 |
5 | 7 | 5 | 6 |
6 | 7 | 6 | 7 |
7 | 7 | 7 | 8(停止迭代) |
- 编写的类
MyRange
具有__iter__
和__next__
两种方法 -
range
没有__next__
方法
image.png
斐波那契数列实现
class Fibs: # 定义一个类
def __init__(self, max): # 传入max参数
self.max = max # 三个属性,三个初始值
self.a = 0
self.b = 1
def __iter__(self): # 返回迭代器本身,说明是可迭代的
return self
def __next__(self): # 迭代器对象
fib = self.a
if fib > self.max:
raise StopIteration
self.a, self.b = self.b, self.a + self.b
return fib
if __name__ == "__main__":
fibs = Fibs(9)
print(list(fibs))
# print([x for x in fibs])
[0, 1, 1, 2, 3, 5, 8]
理解
self.a(前) | self.max | fib | self.a(后) | self.b(前) | self.b(后) |
---|---|---|---|---|---|
0 | 9 | 0 | 1 | 1 | 1 |
1 | 9 | 1 | 1 | 1 | 2 |
1 | 9 | 1 | 2 | 2 | 3 |
2 | 9 | 2 | 3 | 3 | 5 |
3 | 9 | 3 | 5 | 5 | 8 |
5 | 9 | 5 | 8 | 8 | 13 |
8 | 9 | 8 | 13 | 13 | 21 |
13 | 9 | 13 | 停止迭代 |
fib返回值
[0, 1, 1, 2, 3, 5, 8]
列表和元组解析式区别
- 列表可以多次解析
- 元组只能一次解析
网友评论