已知x=zip(‘abc’,’1234’),那么連續兩次執行list(x)會得到什么結果,請分析說明原因
uj5u.com熱心網友回復:
第一次執行list(x),如果列印出來的話是[('a', '1'), ('b', '2'), ('c', '3')]
第二次執行list(x),如果列印出來的話是
[]
至于原因為什么,就要從zip函式的源代碼說起了:
def zip(*iterables):
# zip('abc', '1234') --> Ax By
sentinel = object()
iterators = [iter(it) for it in iterables]
while iterators:
result = []
for it in iterators:
elem = next(it, sentinel)
if elem is sentinel:
return
result.append(elem)
yield tuple(result)
原始碼分析見:https://docs.python.org/zh-cn/3/library/functions.html#zip
因為zip函式中使用了yield陳述句,
所以x=zip(‘abc’,’1234’)后,zip函式并不立即執行,而是使x變成了一個生成器物件。
當成為了生成器物件時,只能通過next函式進行逐一取值。
然而,因為后續陳述句是list(x),這使得生成器x把所有的資料都迭代完全,并全部回傳了。
所以,使得第2個list(x)時,x已經是一個無法迭代的生成器了,也就是只能回傳空值
所以list(空)時,得到結果[]。
樓主,可以用以下代碼驗證理解:
x=zip('abc','1234')
print(next(x))
print(next(x))
print(next(x))
print(next(x) #第4次next因為遇到空值則會發生停止迭代例外
補充說明:
為什么用4個next陳述句,在第4次會發生例外?而使用了函式zip,在list時卻不會發生例外?
那是因為在zip函式源代碼中進行了例外處理(使用object物件進行空值替換)!
所以,在我給你的驗證代碼中,如果把第4次的next陳述句改成如下:
print(next(x, object()))
則不會發生例外了,因為用object物件進行空值替換了。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/82703.html
