在this問題@lazyr詢問如何izip_longest
迭代從here作品下面的代碼:itertools中的izip_longest:迭代器中的IndexError如何工作?
def izip_longest_from_docs(*args, **kwds):
# izip_longest('ABCD', 'xy', fillvalue='-') --> Ax By C- D-
fillvalue = kwds.get('fillvalue')
def sentinel(counter = ([fillvalue]*(len(args)-1)).pop):
yield counter() # yields the fillvalue, or raises IndexError
fillers = repeat(fillvalue)
iters = [chain(it, sentinel(), fillers) for it in args]
try:
for tup in izip(*iters):
yield tup
except IndexError:
pass
當我試圖理解它是如何工作的我偶然到一個問題: 「如果IndexError
是內部人提出那些被髮送到izip_longest
作爲參數的迭代器?「。
然後我寫了一些測試代碼:
from itertools import izip_longest, repeat, chain, izip
def izip_longest_from_docs(*args, **kwds):
# The code is exactly the same as shown above
....
def gen1():
for i in range(5):
yield i
def gen2():
for i in range(10):
if i==8:
raise IndexError #simulation IndexError raised inside the iterator
yield i
for i in izip_longest_from_docs(gen1(),gen2(), fillvalue = '-'):
print('{i[0]} {i[1]}'.format(**locals()))
print('\n')
for i in izip_longest(gen1(),gen2(), fillvalue = '-'):
print('{i[0]} {i[1]}'.format(**locals()))
而事實證明,在itertools
模塊和izip_longest_from_docs
工作中的作用是不同的。
以上代碼的輸出:
>>>
0 0
1 1
2 2
3 3
4 4
- 5
- 6
- 7
0 0
1 1
2 2
3 3
4 4
- 5
- 6
- 7
Traceback (most recent call last):
File "C:/..., line 31, in <module>
for i in izip_longest(gen1(),gen2(), fillvalue = '-'):
File "C:/... test_IndexError_inside iterator.py", line 23, in gen2
raise IndexError
IndexError
因此,它清楚地看到,那的izip_longes
從itertools
代碼並傳播IndexError
異常(因爲我認爲它應該),但izip_longes_from_docs
「吞噬」 IndexError
例外因爲它將sentinel
作爲信號停止迭代。
我的問題是,他們是如何在itertools
模塊的代碼中傳播IndexError
?
@agf我想要的,但我找不到它。感謝您的鏈接!我會看看。 – ovgolovin
@agf它似乎在C:o)對我來說太複雜了。儘管如此,據稱是**的等價物在功能(而不是速度)方面似乎不是絕對等價的。 – ovgolovin
是的,你是對的。 「如果您在本文檔中發現錯誤或想要提出改進建議,請發送電子郵件至[email protected]描述錯誤以及您在何處找到錯誤。如果您有建議如何解決該錯誤,請包括以及「。如果你不喜歡它,我會去做嗎? – agf