入力されたリストのすべての可能な組み合わせを含むリストを作成できる必要があります。たとえば、リスト[1,2,3]
は[1 [1,2] [1,3] 2 [2,3] 3 [1,2,3]]
を返す必要がありますリストは特定の順序である必要はありません。このサイトでは、itertools
を使用する多くの関数を見つけましたが、list
だけが必要なときにオブジェクトを返しています。
itertools.combinations
。例えば:
import itertools
lst = [1, 2, 3]
combs = []
for i in xrange(1, len(lst)+1):
combs.append(i)
els = [list(x) for x in itertools.combinations(lst, i)]
combs.append(els)
これでcombs
がこの値を保持します:
[1, [[1], [2], [3]], 2, [[1, 2], [1, 3], [2, 3]], 3, [[1, 2, 3]]]
はい、それはあなたが提供したサンプル出力とは少し異なりますが、その出力ではすべての可能な組み合わせをリストしていませんでした。
組み合わせのサイズをリストしていますbefore各サイズの実際のリスト、必要なのは単に組み合わせである場合(サンプル出力に表示されるサイズなし)次に、これらの他のバージョンのコードを試してください:
import itertools
lst = [1, 2, 3]
combs = []
for i in xrange(1, len(lst)+1):
els = [list(x) for x in itertools.combinations(lst, i)]
combs.extend(els)
これでcombs
がこの値を保持します:
[[1], [2], [3], [1, 2], [1, 3], [2, 3], [1, 2, 3]]
itertools
モジュールは、リストの代わりにgeneratorsを返しますが、
list(...)
を使用してジェネレータをリストにいつでも変換できます。chain
のcombinations
およびitertools
関数は正常に機能します、ただし、使用する必要があるPython 2.6以降:
import itertools
def all_combinations(any_list):
return itertools.chain.from_iterable(
itertools.combinations(any_list, i + 1)
for i in xrange(len(any_list)))
その後、これを次のように呼び出すことができます。
# as a generator
all_combinations([1,2,3]) # --> <itertools.chain at 0x10ef7ce10>
# as a list
list(all_combinations([1,2,3])) # --> [(1,), (2,), (3,), (1, 2), (1, 3), (2, 3), (1, 2, 3)]
# as a list of lists
[list(l) for l in all_combinations([1,2,3])] # --> [[1], [2], [3], [1, 2], [1, 3], [2, 3], [1, 2, 3]]
以前にジェネレーターを使用したことがない場合は、次のようにジェネレーターをリストであるかのようにループすることに注意してください。
# a generator returned instead of list
my_combinations = all_combinations([1,2,3])
# this would also work if `my_combinations` were a list
for c in my_combinations:
print "Combo", c
"""
Prints:
Combo (1,)
Combo (2,)
Combo (3,)
Combo (1, 2)
Combo (1, 3)
Combo (2, 3)
Combo (1, 2, 3)
"""
パフォーマンスの違いは劇的です。パフォーマンスを比較すると、ジェネレーターの作成がはるかに高速であることがわかります。
# as a generator
all_combinations(range(25)) # timing: 100000 loops, best of 3: 2.53 µs per loop
# as a list
list(all_combinations(range(25))) # timing: 1 loops, best of 3: 9.37 s per loop
いずれの場合でも、すべての組み合わせを繰り返すにはまだ時間がかかりますが、特に探しているものを早期に見つけた場合は、大きな勝利になる可能性があることに注意してください。
Itertoolsモジュールの関数は反復子を返します。これらをリストに変換するために必要なことは、結果に対してlist()
を呼び出すことだけです。
ただし、itertools.combinations
を3回(異なる長さごとに1回)呼び出す必要があるため、list.extend
を使用して、イテレータのすべての要素を最終リストに追加できます。
以下を試してください:
import itertools
in_list = [1, 2, 3]
out_list = []
for i in range(1, len(in_list)+1):
out_list.extend(itertools.combinations(in_list, i))
または、リストの理解として:
out_list = [c for i in range(len(in_list)) for c in itertools.combinations(in_list, i+1)]
これらは次のリストになります。
[(1,), (2,), (3,), (1, 2), (1, 3), (2, 3), (1, 2, 3)]
タプルの代わりにリストが必要な場合、および単一の長さのタプルを値だけに変換するには、以下を実行できます。
out_list = [x[0] if len(x) == 1 else list(x) for x in out_list]
# [1, 2, 3, [1, 2], [1, 3], [2, 3], [1, 2, 3]]
または、単一のアイテムをリストとして残すには:
out_list = map(list, out_list)
ループ内でitertools.combinations
を使用して問題を解決できます。
>>> l = [1,2,3]
>>> comb = []
>>> for i in range(len(l)):
... comb += itertools.combinations(l,i+1)
...
>>> comb
[(1,), (2,), (3,), (1, 2), (1, 3), (2, 3), (1, 2, 3)]
そしてそれらをリストとして欲しい場合:
>>> comb_list = [ list(t) for t in comb ]
>>> comb_list
[[1], [2], [3], [1, 2], [1, 3], [2, 3], [1, 2, 3]]
EDIT:組み合わせの最初のパラメーターは反復可能で、2番目のパラメーターは結果のタプルの長さです(この場合、1
からlen(l)
)。
組み合わせの詳細: http://docs.python.org/library/itertools.html#itertools.combinations
l = [1,2,3]
combs = reduce(lambda x, y: list(itertools.combinations(l, y)) + x, range(len(l)+1), [])
1つのライナーが必要な場合。
ここで他の答えを簡単なPython 3の例に要約する価値があると思います:
from itertools import chain, combinations
def all_combinations(array):
return chain(*(list(combinations(array, i + 1)) for i in range(len(array))))
これは、値を表示するために反復可能を返します:
>>> print(list(all_combinations((1, 2, 3))))
[(1,), (2,), (3,), (1, 2), (1, 3), (2, 3), (1, 2, 3)]