可迭代对象
可迭代对象是一种可以使用for…in…语句进行循环的对象,像str/bytes、list/tuple、set/dict以及迭代器、生成器都称为可迭代对象。可迭代对象实现了__iter__方法,用于返回迭代器。
k = [1, 2, 3, 4, 5, 6]
print(k.__iter__())
print(next(k))
运行结果:
由上可知,迭代器是可迭代对象,可迭代对象不一定是迭代器。
迭代器
包含了 __ iter__ 和 __ next__ ⽅法的对象都是一个迭代器(iterator)。
__ iter__ 得到⼀个迭代器,迭代器的__ iter__()返回⾃身,__ next__ 返回迭代器下⼀个值。
如果容器中没有更多元素,则抛出 StopIteration 异常。
k = [1, 2, 3, 4, 5, 6]
ik = k.__iter__()
print(next(ik))
print(ik.__next__())
print(next(ik))
print(ik.__next__())
print(next(ik))
print(ik.__next__())
print(next(ik))
运行结果:
如果我们先next3个,再使用for循环看看出现怎么的结果???
k = [1, 2, 3, 4, 5, 6]
ik = k.__iter__()
print(next(ik))
print(next(ik))
print(next(ik))
运行结果:
k = [1, 2, 3, 4, 5, 6]
ik = k.__iter__()
print(next(ik))
print(next(ik))
print(next(ik))
for i in ik:
print(i)
运行结果:
我们发现其会接着上面继续生成,记录自己的状态。
自定义迭代器
class A:
def __init__(self):
self.count = 3
def __iter__(self):
return self
def __next__(self):
if self.count > 0:
self.count -= 1
return 'a'
else:
raise StopIteration
a = A()
print(next(a))
print(next(a))
print(next(a))
print(next(a))
运行结果:
StopIteration其实不是什么错误,只是用来控制停止迭代的行为。
通过迭代器的方法来写range类
class Range:
def __init__(self, start, stop=None, step=1):
if stop is None:
self.start = 0
self.stop = start
else:
self.start = start
self.stop = stop
self.step = step
def __iter__(self):
return self
def __next__(self):
if self.start < self.stop:
result = self.start
self.start += self.step
return result
else:
raise StopIteration
for i in Range(5):
print(i)
for i in Range(6, 10, 2):
print(i)
运行结果:
生成器
⽣成器(generator)是⼀种特殊的迭代器, 不需要自定义 __ iter__ 和 __ next__
def foo():
for i in range(10):
yield i
g = foo()
print(type(g))
print(next(g))
print(g.__next__())
print(g.__iter__())
运行结果:
生成器的误解:
def foo():
print(111)
yield 222
print(333)
yield 444
print(555)
g = foo()
x = next(g)
运行结果:
在执行g = foo()时,不会执行foo()函数中的任何东西
def foo():
print(111)
yield 222
print(333)
yield 444
print(555)
g = foo()
x = next(g)
print(x)
运行结果:
def foo():
print(111)
yield 222
print(333)
yield 444
print(555)
g = foo()
for i in g:
print('i=', i)
运行结果:
itertools模块
导入itertools模块
itertools.cycle:循环
import itertools
x = itertools.cycle('abcd')
print(next(x))
print(next(x))
print(next(x))
print(next(x))
print(next(x))
print(next(x))
运行结果:
itertools.chain:成链式
import itertools
x = itertools.chain('abc', [1, 2, 3], {4, 5, 6})
for i in x:
print(i)
运行结果:
itertools.repeat:重复
import itertools
x = itertools.repeat('abcd', 3)
for i in x:
print(i)
运行结果:
itertools.combinations:组合
import itertools
for x in itertools.combinations(['A', 'B', 'C'], 2):
print(x)
运行结果: