迭代是数据处理的一种基础操作,扫描内存中放不下的数据时,找到一种惰性获取数据想,按需一次获取一个数据项
可迭代对象
可迭代对象:实现__getitem__方法或__iter__方法的对象即是可迭代对象,其中__getitem__方法可以根据参数
返回从0开始索引的元素,而__iter__方法会返回迭代器
迭代器
迭代器:实现了__iter__方法和__next__方法的对象是迭代器,其中__iter__方法返回迭代器本身及self本身,而__next__
方法返回下一个元素
如以下例子
```s = 'python'
for i in s:
print(i)
#字符串s为可迭代对象,背后有迭代器
it = iter(s)#构建迭代器it
while True:
try:
print(next(it))
except StopIteration:
del it
break
s = 'python'
for i in s:
print(i)
#以类的方法实现
class Sentence:
def __init__(self,txt):
self.txt = txt
self.words = txt.split(' ')
def __getitem__(self,index):
return self.words[index]
def __len__(self):
return len(self.words)
s = Sentence('Life is short you need python')
print(type(s))
for c in s:
print(c)
'''
生成器函数,只要在python中定义了yield关键字,该函数就是生成器函数。
生成器函数就是生成器工厂,用于产生生成器对象
所有的生成器都是迭代器
'''
class Sentense:
def __init__(self,txt):
self.txt = txt
self.words = txt.split(' ')
def __iter__(self):
return SentenceIterator(self.words)
class SentenceIterator:
def __init__(self,words):
self.words = words
self.index = 0
def __next__(self):
try:
word = self.words[self.index]
except IndexError:
raise StopIteration()
self.index += 1
return word
def __iter__(self):
return self
s = Sentense('Life is short you')
for i in s:
print(i)
#使用生成器方法简化
#在此示例中,迭代器其实是生成器对象,每次调用__iter__方法都会自动创建,因为这里的__iter__方法是
#生成器函数
class Sentence:
def __init__(self,text):
self.text = text
self.words = text.split(' ')
def __iter__(self):
for word in self.words:
yield word
def gen_123():
print('start')
yield 1
print('continue')
yield 2
print('end')
yield 3
gen_123()
for i in gen_123():
print(i)
'''
其逻辑为:
1、在for循环中第一次隐式调用next()函数,会打印start,然后停在第一个yield语句,生成值'1'
2、在for循环中第二次隐式调用next()函数,打印'continue',停在第二个yield语句,生成值'2'
3、最后一次调用next()函数,打印'end'达到函数定义体的末尾,导致生成器抛出StopIteration异常
for循环捕获异常
'''
'''
迭代器与生成器差异,迭代器实现__iter__与__next__方法
生成器使用yield关键字
差异在于:迭代器会返回已有集合中的元素,生成器会生成元素并通过yield关键字返回
'''
def gen_ab():
print('start')
yield 'a'
print('continue')
yield 'b'
print('end')
yield 'c'
res = [x for x in gen_ab()]#列表生成式'
res1 = (x for x in gen_ab())#生成器表达式,返回的是生成器对象,可利用for循环
print(res)
for i in res1:
print(i)
#yiled from
def gen_num(num):
for i in range(num):
yield i
def chain(*gens):
for g in gens:
for i in g:
yield i
g1 = gen_num(5)
g2 = gen_num(10)
result = chain(g1,g2)
print(list(result))
def new_chain(*gens):
for i in gens:
yield from i
g4 = new_chain(gen_num(6),gen_num(7))
print(list(g4))
'''
yield from会创建通道,把内层生成器直接与外层生成器的客户端联系起来
把生成器当成协程使用,这个通道特别重要
生成器是用于生成供迭代的数据;协程是数据的消费者;协程与迭代无关
'''