web-dev-qa-db-ja.com

2つのリストを次々に反復する

2つのリストがありますlist1およびlist2の数、そして私は同じ指示でそれらを繰り返したいと思います。このような:

for item in list1:
  print(item.amount)
  print(item.total_amount)

for item in list2:
  print(item.amount)
  print(item.total_amount)

しかし、それは冗長に感じます。 for item in list1 + list2:、しかしそれは実行時間の代償があります。

時間を無駄にすることなくそれを行う方法はありますか?

15
Dubon

これはitertools.chainで実行できます。

import itertools

l1 = [1, 2, 3, 4]
l2 = [5, 6, 7, 8]

for i in itertools.chain(l1, l2):
    print(i, end=" ")

印刷されます:

1 2 3 4 5 6 7 8 

ドキュメントによると、chainは次のことを行います。

最初の反復可能オブジェクトから要素がなくなるまで要素を返すイテレータを作成し、すべての反復可能要素がなくなるまで次の反復可能オブジェクトに進みます。

リストにリストがある場合は、itertools.chain.from_iterableを使用できます。

l = [l1, l2]
for i in itertools.chain.from_iterable(l):
    print(i, end=" ")

同じ結果が得られます。

このためのモジュールをインポートしたくない場合は、そのための関数を作成するのは非常に簡単です。

def custom_chain(*it):
    for iterab in it:
        yield from iterab

これにはPython 3、Python 2の場合、ループを使用してyieldだけ戻す必要があります。

def custom_chain(*it):
    for iterab in it:
        for val in iterab:
            yield val

前のものに加えて、Python 3.5とその拡張されたアンパックの一般化により、リストリテラルでアンパックすることもできます。

for i in [*l1, *l2]:
    print(i, end=" ")

これはl1 + l2よりもわずかに高速ですが、それでもリストを作成し、それを破棄します。最終的な解決策としてのみそれのために行きます。

chainは機能しますが、単一の関数を1回呼び出すだけでモジュールをインポートするのはやり過ぎだと感じる場合は、その動作をインラインで複製できます。

for seq in (list1, list2):
  for item in seq:
    print(item.amount)
    print(item.total_amount)

(list1、list2)タプルの作成は、リストの長さに関してO(1)であるため、リストを連結する場合に比べて有利です。

2
Kevin

これはどう:

for item in list1 + list2:
    print(item.amount)
    print(item.total_amount)

たった3行

0
Christian Gao