リストのリストのすべての組み合わせ


240

私は基本的に組み合わせの Pythonバージョンを探していますList<List<int>>

リストのリストを考えると、リスト間の項目の可能なすべての組み合わせを提供する新しいリストが必要です。

[[1,2,3],[4,5,6],[7,8,9,10]] -> [[1,4,7],[1,4,8],...,[3,6,10]]

リストの数は不明なので、すべてのケースで機能するものが必要です。優雅さのボーナスポイント!

回答:


428

あなたは必要ですitertools.product

>>> import itertools
>>> a = [[1,2,3],[4,5,6],[7,8,9,10]]
>>> list(itertools.product(*a))
[(1, 4, 7), (1, 4, 8), (1, 4, 9), (1, 4, 10), (1, 5, 7), (1, 5, 8), (1, 5, 9), (1, 5, 10), (1, 6, 7), (1, 6, 8), (1, 6, 9), (1, 6, 10), (2, 4, 7), (2, 4, 8), (2, 4, 9), (2, 4, 10), (2, 5, 7), (2, 5, 8), (2, 5, 9), (2, 5, 10), (2, 6, 7), (2, 6, 8), (2, 6, 9), (2, 6, 10), (3, 4, 7), (3, 4, 8), (3, 4, 9), (3, 4, 10), (3, 5, 7), (3, 5, 8), (3, 5, 9), (3, 5, 10), (3, 6, 7), (3, 6, 8), (3, 6, 9), (3, 6, 10)]

20
誰かがアスタリスクの意味を説明でき*aますか?
セラーノ2013

52
*aこれらは、関数またはメソッドに渡される引数であることを意味します。参照にdef fn(a,b,c):応答しfn(*[1,2,3]) ます
mjallday

1
@mjallday、これらの組み合わせを追加することも可能でしょうか:(7,4,1)、(8,4,1)、(9,4,1)、(10,4,1)、(7,5、 1)、(8、5、1)、(9、5、1)、(10、5、1)など?
Reman、2016

1
完全にあなたが取得したいものをクリアしていないが、それであれば、例えば、また、あなたが取るAAラッパー関数を使用することができ、各タプルの逆@Reman a入力としては、反復処理itertools.product(*a)yieldによって生成タプルの両方だitertools(と逆バージョンをたとえば、リストを作成し、reverse()それをタプルに変換します)。新しい質問をするのが一番です。
Joachim Wagner

24

最もエレガントなソリューションは、Python 2.6でitertools.productを使用することです

Python 2.6を使用していない場合、itertools.productのドキュメントには、製品を「手動」で実行するための同等の関数が実際に示されています。

def product(*args, **kwds):
    # product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dy
    # product(range(2), repeat=3) --> 000 001 010 011 100 101 110 111
    pools = map(tuple, args) * kwds.get('repeat', 1)
    result = [[]]
    for pool in pools:
        result = [x+[y] for x in result for y in pool]
    for prod in result:
        yield tuple(prod)

19
listOLists = [[1,2,3],[4,5,6],[7,8,9,10]]
for list in itertools.product(*listOLists):
  print list;

私が最初に出会ったときと同じように、それがエレガントであるとあなたが願っています。


5
そのセミコロンはどうしたの?:)
パオロベルガンティーノ

3
習慣の力。Pythonでセミコロンを1つ入れて、C / Javaプログラマーを支援する方法が気に入っています。しかし、それは明らかです。print( "foo");のようなことをすると、実際にはステートメントの終了文字ではありません。これはCやJavaでは完全に合法ですが(無意味です)、Pythonでは禁止されています。
マシューFlaschen

5

Numpyはそれを行うことができます:

 >>> import numpy
 >>> a = [[1,2,3],[4,5,6],[7,8,9,10]]
 >>> [list(x) for x in numpy.array(numpy.meshgrid(*a)).T.reshape(-1,len(a))]
[[ 1, 4, 7], [1, 5, 7], [1, 6, 7], ....]

誰かがこれを説明できますか?
ashishv 2017

5

このタスクの完全な再帰で問題はありません。文字列で動作するバージョンが必要な場合、これはニーズに合う可能性があります。

combinations = []

def combine(terms, accum):
    last = (len(terms) == 1)
    n = len(terms[0])
    for i in range(n):
        item = accum + terms[0][i]
        if last:
            combinations.append(item)
        else:
            combine(terms[1:], item)


>>> a = [['ab','cd','ef'],['12','34','56']]
>>> combine(a, '')
>>> print(combinations)
['ab12', 'ab34', 'ab56', 'cd12', 'cd34', 'cd56', 'ef12', 'ef34', 'ef56']

3

これにはベースPythonを使用できます。コードには、リストのリストをフラット化する関数が必要です。

def flatten(B):    # function needed for code below;
    A = []
    for i in B:
        if type(i) == list: A.extend(i)
        else: A.append(i)
    return A

次に、実行できます:

L = [[1,2,3],[4,5,6],[7,8,9,10]]

outlist =[]; templist =[[]]
for sublist in L:
    outlist = templist; templist = [[]]
    for sitem in sublist:
        for oitem in outlist:
            newitem = [oitem]
            if newitem == [[]]: newitem = [sitem]
            else: newitem = [newitem[0], sitem]
            templist.append(flatten(newitem))

outlist = list(filter(lambda x: len(x)==len(L), templist))  # remove some partial lists that also creep in;
print(outlist)

出力:

[[1, 4, 7], [2, 4, 7], [3, 4, 7], 
[1, 5, 7], [2, 5, 7], [3, 5, 7], 
[1, 6, 7], [2, 6, 7], [3, 6, 7], 
[1, 4, 8], [2, 4, 8], [3, 4, 8], 
[1, 5, 8], [2, 5, 8], [3, 5, 8], 
[1, 6, 8], [2, 6, 8], [3, 6, 8], 
[1, 4, 9], [2, 4, 9], [3, 4, 9], 
[1, 5, 9], [2, 5, 9], [3, 5, 9], 
[1, 6, 9], [2, 6, 9], [3, 6, 9], 
[1, 4, 10], [2, 4, 10], [3, 4, 10], 
[1, 5, 10], [2, 5, 10], [3, 5, 10], 
[1, 6, 10], [2, 6, 10], [3, 6, 10]]

-1
from itertools import product 
list_vals = [['Brand Acronym:CBIQ', 'Brand Acronym :KMEFIC'],['Brand Country:DXB','Brand Country:BH']]
list(product(*list_vals))

出力:

[( 'ブランドの頭字語:CBIQ'、 'ブランドの国:DXB')、
( 'ブランドの頭字語:CBIQ'、 'ブランドの国:BH')、
( 'ブランドの頭字語:KMEFIC'、 'ブランドの国:DXB')、
( 'ブランドの頭字語:KMEFIC'、 'ブランドの国:BH')]


この回答は、組み込み関数を使用する唯一の回答であるため、受け入れる必要があります。また、あらゆる種類の異種に対しても機能することを強調しています。
pedjjj

この回答は、何年も前に提供された回答とどう違うのですか?
Dawid Laszuk
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.