可迭代对象 什么是可迭代对象 简单理解:可以被for遍历的对象
代码层面:如果一个对象实现了iter 方法,那么这个对象就是可迭代对象
1 2 3 4 5 6 str_iterable = "hello world!" for x in str_iterable: print (x)
h
e
l
l
o
w
o
r
l
d
!
1 2 print (str_iterable.__iter__())print (iter (str_iterable))
<str_iterator object at 0x7fdfc5c2ac20>
<str_iterator object at 0x7fdfc5c2ad40>
可迭代对象之间的共同点 可以借助一个方法来看不同可迭代对象之间,有什么共同的方法或者属性
1 2 3 4 5 6 7 8 9 10 def common_attrs_of_iterable (*iterables ): res = set () for iterable in iterables: if not res: res = set (dir (iterable)) else : res &= set (dir (iterable)) res -= set (dir (object )) return res
1 2 3 4 import sysiterables = ("asada" , ["1" ,"2" ,3 ], {"1" : 2 }, set (), open (sys.argv[0 ])) common_attrs = common_attrs_of_iterable(*iterables) print (common_attrs)
{'__iter__'}
运行上述代码可以看到,可迭代对象都实现了__iter__
方法。
1 2 for iterable in iterables: print (iter (iterable))
<str_iterator object at 0x7fdfc5c2bdc0>
<list_iterator object at 0x7fdfc5c2bdc0>
<dict_keyiterator object at 0x7fdfc4290e50>
<set_iterator object at 0x7fdfc42743c0>
<_io.TextIOWrapper name='/opt/conda/lib/python3.10/site-packages/ipykernel_launcher.py' mode='r' encoding='UTF-8'>
可以发现,iter方法作用于可迭代对象,返回了一个迭代器对象。
迭代器 在Python 文档中明确指出了,迭代器必须同时实现__next__
和__iter__
方法,这称之为「迭代器协议」。根据这个协议,迭代器必须是可迭代的,换言之,「迭代器」是一种「可迭代对象」。缺少了__iter__
方法的迭代器是不完整的,不符合迭代器协议的要求。所有迭代器的__iter__
方法都只要干篇一律的return self 即可。
迭代器的共同属性 1 2 3 iterators = [iter (iterable) for iterable in iterables] r = common_attrs_of_iterable(*iterators) print (r)
{'__next__', '__iter__'}
如何迭代 如何手动迭代?
构建迭代器iter(iterable)
迭代next(iterator)取值
捕获StopIteration异常结束迭代
1 2 3 actions = ["唱跳" , "Rap" , "篮球" ] action_iterator = iter (actions) print (action_iterator)
<list_iterator object at 0x7fdfc5c2b520>
'唱跳'
'Rap'
'篮球'
---------------------------------------------------------------------------
StopIteration Traceback (most recent call last)
Cell In[24], line 1
----> 1 next(action_iterator)
StopIteration:
自定义迭代器 手动next迭代 1 2 3 4 5 6 7 8 9 10 11 class CustomIterator : def __init__ (self, actions ): self.actions = actions self.index = 0 def __next__ (self ): while self.index < len (self.actions): action = self.actions[self.index] self.index += 1 return action raise StopIteration
1 2 3 custom_iterator = CustomIterator(actions) while True : print (next (custom_iterator))
唱跳
Rap
篮球
---------------------------------------------------------------------------
StopIteration Traceback (most recent call last)
Cell In[32], line 3
1 custom_iterator = CustomIterator(actions)
2 while True:
----> 3 print(next(custom_iterator))
Cell In[31], line 11, in CustomIterator.__next__(self)
9 self.index += 1
10 return action
---> 11 raise StopIteration
StopIteration:
1 2 3 4 custom_iterator = CustomIterator(actions) for x in custom_iterator: print (x)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[33], line 3
1 # 使用for in遍历
2 custom_iterator = CustomIterator(actions)
----> 3 for x in custom_iterator:
4 print(x)
TypeError: 'CustomIterator' object is not iterable
使用for in自动遍历 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class CustomIterator : def __init__ (self, actions ): self.actions = actions self.index = 0 def __next__ (self ): while self.index < len (self.actions): action = self.actions[self.index] self.index += 1 return action raise StopIteration def __iter__ (self ): return self
1 2 3 custom_iterator = CustomIterator(actions) for x in custom_iterator: print (x)
唱跳
Rap
篮球
无限产生数据 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 from random import randomclass Random : def __iter__ (self ): return self def __next__ (self ): return random() i = 0 for x in Random(): print (x) i += 1 if i == 15 : break
0.821488499889332
0.7726247502230905
0.8130058108108277
0.9370384548715419
0.5028830329931709
0.10089818387325744
0.20126577437316662
0.41492810575332495
0.9845745266851457
0.912745925842808
0.21538545269372233
0.1509464699891857
0.9663588740624246
0.9287065525926113
0.5975031338963481