_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)
はどのように機能しますか?より冗長なコードで記述された場合、どのようになりますか?
他の素晴らしい回答とコメントは、 argument unpacking と Zip() .
Ignacio および jukatzel のように、Zip()
に同じイテレータへの3つの参照を渡し、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、None
の初期引数でmap()
で同じ結果を得ることができます:
_>>> 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 /
すべての回答で見落とされていることの1つは(おそらくイテレータに精通している人には明らかなことですが)、他の人にはそれほど明白ではないことです。
同じイテレータがあるため、それが消費され、残りの要素がZipによって使用されます。したがって、iterなどではなく、単にリストを使用した場合。
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)]
イテレータを使用して、値をポップし、使用可能な状態を維持するため、Zipの場合、0が消費されると1が使用可能になり、2などが使用されます。非常に微妙なことですが、かなり賢い!!!
iter(s)
はsの反復子を返します。
[iter(s)]*n
は、sに対してn回同じイテレータのリストを作成します。
したがって、Zip(*[iter(s)]*n)
を実行すると、リストの3つのイテレータすべてから順番にアイテムが抽出されます。すべての反復子は同じオブジェクトであるため、リストをn
のチャンクにグループ化するだけです。
この方法でZipを使用するためのアドバイスの一言。リストの長さが均等に割り切れない場合、リストを切り捨てます。この問題を回避するには、fill値を受け入れることができる場合は 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
おそらく、pythonインタープリターまたはipython
で_n = 2
_で何が起こっているかを確認する方が簡単です:
_In [35]: [iter("ABCDEFGH")]*2
Out[35]: [<iterator at 0x6be4128>, <iterator at 0x6be4128>]
_
したがって、同じイテレータオブジェクトを指す2つのイテレータのリストがあります。オブジェクトのiter
はイテレータオブジェクトを返し、このシナリオでは、_*2
_ python構文シュガー。イテレータも実行されるため、イテレータは2回同じです。 1回だけ。
さらに、 Zip
は任意の数の反復可能要素( sequences are iterables )を取り、それぞれのi番目の要素からTupleを作成します入力シーケンス。今回のケースでは両方のイテレータが同一であるため、Zipは出力の2要素タプルごとに同じイテレータを2回移動します。
_In [41]: help(Zip)
Help on built-in function Zip in module __builtin__:
Zip(...)
Zip(seq1 [, seq2 [...]]) -> [(seq1[0], seq2[0] ...), (...)]
Return a list of tuples, where each Tuple contains the i-th element
from each of the argument sequences. The returned list is truncated
in length to the length of the shortest argument sequence.
_
npacking(_*
_)演算子 は、イテレータが枯渇するまで実行します。この場合、2要素のタプルを作成するための十分な入力がなくなるまでです。
これはn
の任意の値に拡張でき、Zip(*[iter(s)]*n)
は説明どおりに機能します。