インターネット上でそれらの違いと、なぜどちらを選択するのかを見ることができる有効な例を見つけることができませんでした。
最初の引数はそれぞれ反復可能な0個以上の引数を取り、2番目の引数は反復可能な引数を生成することが期待される1つの引数を取ります。
_from itertools import chain
chain(list1, list2, list3)
iterables = [list1, list2, list3]
chain.from_iterable(iterables)
_
ただし、iterables
には、反復可能要素を生成する任意の反復子を指定できます。
_def gen_iterables():
for i in range(10):
yield range(i)
itertools.chain.from_iterable(gen_iterables())
_
通常、2番目の形式を使用するのは便利なケースですが、入力反復可能オブジェクトを遅延してループ処理するため、無限数の有限反復子を連鎖させることができる唯一の方法でもあります。
_def gen_iterables():
while True:
for i in range(5, 10):
yield range(i)
chain.from_iterable(gen_iterables())
_
上記の例は、停止することはないが、単一のrange()
呼び出しが必要とするよりも多くのメモリを消費することのない数値の循環パターンを生成する反復可能要素を提供します。
彼らは非常に似たようなことをします。少数の反復可能オブジェクトの場合、itertools.chain(*iterables)
およびitertools.chain.from_iterable(iterables)
も同様に実行します。
from_iterables
の主な利点は、呼び出し時にすべてのイテラブルを使用できる必要がないため、多数の(潜在的に無限の)イテラブルを処理できることです。
有効な例を見つけることができませんでした... [
chain
とchain.from_iterable
]の違いを見ることができます。
受け入れられた答えは徹底的です。迅速なアプリケーションを探している人のために、いくつかのリストをフラット化することを検討してください。
list(itertools.chain(["a", "b", "c"], ["d", "e"], ["f"]))
# ['a', 'b', 'c', 'd', 'e', 'f']
これらのリストを後で再利用したい場合がありますので、リストの反復可能にします:
iterable = (["a", "b", "c"], ["d", "e"], ["f"])
試行
ただし、chain
にiterableを渡すと、平坦化されていない結果が得られます。
list(itertools.chain(iterable))
# [['a', 'b', 'c'], ['d', 'e'], ['f']]
どうして? oneアイテム(タプル)を渡しました。 chain
は各リストを個別に必要とします。
ソリューション
可能な場合は、反復可能ファイルを展開できます。
list(itertools.chain(*iterable))
# ['a', 'b', 'c', 'd', 'e', 'f']
list(itertools.chain(*iter(iterable)))
# ['a', 'b', 'c', 'd', 'e', 'f']
より一般的には、.from_iterable
を使用します(無限反復子でも機能します)。
list(itertools.chain.from_iterable(iterable))
# ['a', 'b', 'c', 'd', 'e', 'f']
g = itertools.chain.from_iterable(itertools.cycle(iterable))
next(g)
# "a"
それを見る別の方法:
chain(iterable1, iterable2, iterable3, ...)
は、持っているイテレート可能オブジェクトがすでにわかっている場合に使用するため、これらのコンマ区切りの引数として記述することができます。
chain.from_iterable(iterable)
は、イテラブル(iterable1、iterable2、iterable3など)が別のイテラブルから取得される場合に使用します。