リストを与えられた
l = [1, 7, 3, 5]
連続するリストアイテムのすべてのペアを反復処理したい(1,7), (7,3), (3,5)
、つまり.
for i in xrange(len(l) - 1):
x = l[i]
y = l[i + 1]
# do something
私はこれをよりコンパクトな方法で、たとえば
for x, y in someiterator(l): ...
組み込みのPython反復子を使用してこれを行う方法はありますか?itertools
モジュールに解決策があるはずですが、私はそれを理解できません。
Zip を使用するだけです
>>> l = [1, 7, 3, 5]
>>> for first, second in Zip(l, l[1:]):
... print first, second
...
1 7
7 3
3 5
提案されたように、新しいリストを作成したくない非常に長いリストに対して、izip
でitertools
関数を使用することを検討するかもしれません。
import itertools
for first, second in itertools.izip(l, l[1:]):
...
Itertoolsレシピのpairwise
を見てください: http://docs.python.org/2/library/itertools.html#recipes
そこから引用:
def pairwise(iterable):
"s -> (s0,s1), (s1,s2), (s2, s3), ..."
a, b = tee(iterable)
next(b, None)
return izip(a, b)
一般バージョン
任意の正の自然サイズのタプルを生成する一般的なバージョンは、次のようになります。
def nwise(iterable, n=2):
iters = tee(iterable, n)
for i, it in enumerate(iters):
next(islice(it, i, i), None)
return izip(*iters)
このような汎用のgrouper
ジェネレーターを作成します
def grouper(input_list, n = 2):
for i in xrange(len(input_list) - (n - 1)):
yield input_list[i:i+n]
サンプル実行1
for first, second in grouper([1, 7, 3, 5, 6, 8], 2):
print first, second
出力
1 7
7 3
3 5
5 6
6 8
サンプル実行1
for first, second, third in grouper([1, 7, 3, 5, 6, 8], 3):
print first, second, third
出力
1 7 3
7 3 5
3 5 6
5 6 8
Zip
を使用できます。
>>> list(Zip(range(5), range(2, 6)))
[(0, 1), (1, 2), (2, 3), (3, 4), (4, 5)]
ジッパーのように、ペアを作成します。したがって、2つのリストを混在させるには、次のようにします。
>>> l = [1,7,3,5]
>>> list(Zip(l[:-1], l[1:]))
[(1, 7), (7, 3), (3, 5)]
その後、反復は次のようになります
for x, y in Zip(l[:-1], l[1:]):
pass
理解を伴うnwiseへのsberryのアプローチを一般化する:
def nwise(lst, k=2):
return list(Zip(*[lst[i:] for i in range(k)]))
例えば
nwise(list(range(10)),3)
[(0、1、2)、(1、2、3)、(2、3、4)、(3、4、5)、(4、5、6)、(5、6、7)、( 6、7、8)、(7、8、9)]