s = [1,2,3,4,5,6,7,8,9]
n = 3
zip(*[iter(s)]*n) # returns [(1,2,3),(4,5,6),(7,8,9)]
zip(*[iter(s)]*n)
如何工作?如果使用更詳細的代碼編寫它會是什麼樣子?zip(* [iter(s)] * n)在Python中如何工作?
s = [1,2,3,4,5,6,7,8,9]
n = 3
zip(*[iter(s)]*n) # returns [(1,2,3),(4,5,6),(7,8,9)]
zip(*[iter(s)]*n)
如何工作?如果使用更詳細的代碼編寫它會是什麼樣子?zip(* [iter(s)] * n)在Python中如何工作?
iter(s)
返回s的迭代器。
[iter(s)]*n
列出了n次與s相同的迭代器。
因此,在做zip(*[iter(s)]*n)
時,它會從列表中的所有三個迭代器中按順序提取一個項目。由於所有的迭代器都是同一個對象,因此它只是按照n
的大塊對列表進行分組。
不是'相同列表的迭代器',而是'n次相同的迭代器對象'。不同的迭代器對象不共享狀態,即使它們具有相同的列表。 – 2010-02-09 23:41:28
謝謝,糾正。的確,那正是我所「想」的,但寫了別的東西。 – sttwister 2010-02-10 19:44:08
其他很好的答案和評論很好地解釋了argument unpacking和zip()的作用。
由於Ignacio和ujukatzel說,你傳遞給zip()
三個引用到相同的迭代器和zip()
,使3元組整數,爲了-從每個參考迭代器:
1,2,3,4,5,6,7,8,9 1,2,3,4,5,6,7,8,9 1,2,3,4,5,6,7,8,9
^ ^ ^
^ ^ ^
^ ^ ^
而且因爲你索要更詳細的代碼示例:
chunk_size = 3
L = [1,2,3,4,5,6,7,8,9]
# iterate over L in steps of 3
for start in range(0,len(L),chunk_size): # xrange() in 2.x; range() in 3.x
end = start + chunk_size
print L[start:end] # three-item chunks
繼start
和end
值:
[0:3) #[1,2,3]
[3:6) #[4,5,6]
[6:9) #[7,8,9]
FWIW,你可以用map()
與None
初始參數得到同樣的結果:
>>> map(None,*[iter(s)]*3)
[(1, 2, 3), (4, 5, 6), (7, 8, 9)]
更多關於zip()
和map()
:http://muffinresearch.co.uk/archives/2007/10/16/python-transposing-lists-with-map-and-zip/
這不是迭代器的三個副本,它是同一個迭代器對象的三倍:) – 2010-02-10 04:46:43
一個使用拉鍊這個建議的話辦法。它會截斷你的列表,如果它的長度不能被整除。要解決此問題,您可以使用itertools.izip_longest,前提是您可以接受填充值。或者你可以使用這樣的事情:
def n_split(iterable, n):
num_extra = len(iterable) % n
zipped = zip(*[iter(iterable)] * n)
return zipped if not num_extra else zipped + [iterable[-num_extra:], ]
用法:
for ints in n_split(range(1,12), 3):
print ', '.join([str(i) for i in ints])
打印:
1, 2, 3
4, 5, 6
7, 8, 9
10, 11
這已經記錄在'itertools'食譜中:http://docs.python.org/2/library/itertools.html#recipes'石斑魚'。無需重新發明輪子 – jamylak 2013-04-16 07:05:59
我認爲,在所有的答案錯過了(可能很明顯,對於熟悉的一件事迭代器),但對其他人不那麼明顯 -
由於我們有相同的迭代器,它得到s消耗,其餘元素由zip使用。所以,如果我們只是使用列表而不是它,例如。
l = range(9)
zip(*([l]*3)) # note: not an iter here, the lists are not emptied as we iterate
# output
[(0, 0, 0), (1, 1, 1), (2, 2, 2), (3, 3, 3), (4, 4, 4), (5, 5, 5), (6, 6, 6), (7, 7, 7), (8, 8, 8)]
使用迭代器,彈出的值,僅保留剩餘可用,所以對於拉鍊一旦0被消耗1是可用的,然後2等。一個非常微妙的東西,但很聰明!
+1,你救了我!假設大家都知道這一點,我不能相信其他答案跳過了這個重要的細節。你能否提供包含這些信息的文檔? – 2016-10-06 19:27:33
也看看這裏它是如何工作的也解釋:http://stackoverflow.com/questions/2202461/yield-multiple-objects-at-a-time-from-an-iterable-object/2202485# 2202485 – 2010-02-09 23:22:24
如果這裏的答案還不夠,我在這裏發表博文:http://telliott99.blogspot.com/2010/01/chunks-of-sequence-in-python.html – telliott99 2010-02-10 00:22:35
儘管非常有趣,但這種技巧必須去對付Python的核心「可讀性」值! – Demis 2015-11-26 07:42:42