web-dev-qa-db-fra.com

Toutes les combinaisons d'une liste de listes

Je recherche une version python de Combinaison de List<List<int>>

Étant donné une liste de listes, j'ai besoin d'une nouvelle liste qui donne toutes les combinaisons possibles d'éléments entre les listes.

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

Le nombre de listes étant inconnu, j'ai besoin de quelque chose qui fonctionne dans tous les cas. Des points bonus pour l'élégance!

181
Lin

vous avez besoin de 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)]
331
SilentGhost

La solution la plus élégante consiste à utiliser itertools.product in python 2.6.

Si vous n'utilisez pas Python 2.6, la documentation d'itertools.product affiche en fait une fonction équivalente permettant de faire le produit de manière "manuelle":

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)
23
Jarret Hardie
listOLists = [[1,2,3],[4,5,6],[7,8,9,10]]
for list in itertools.product(*listOLists):
  print list;

J'espère que vous trouverez cela aussi élégant que je l'ai fait quand je l'ai rencontré pour la première fois.

18
Matthew Flaschen

Rien de mal à une récursion directe pour cette tâche, et si vous avez besoin d'une version qui fonctionne avec des chaînes, cela pourrait répondre à vos besoins:

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
duanev

Numpy peut le faire:

 >>> 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], ....]
3

On peut utiliser la base python pour cela: 

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

prod = 1
for sublist in L:   prod *= len(sublist)  # find how many combinations will be there (product of lengths of sublists)
outlist = [[] for i in range(prod)]       # create a list of empty lists for combinations
for sublist in L:                         # for each sublist
    oi=0; sli=0                           # indices for outlist and sublist
    while oi < len(outlist):
        outlist[oi].append(sublist[sli])  # add its items to different combination lists
        oi += 1; sli += 1
        if sli >= len(sublist): sli = 0   # recycle the items
print(outlist)

Sortie:

[[1, 4, 7], [2, 5, 8], [3, 6, 9], [1, 4, 10], [2, 5, 7], [3, 6, 8], [1, 4, 9], [2, 5, 10], [3, 6, 7], [1, 4, 8], [2, 5, 9], [3, 6, 10], [1, 4, 7], [2, 5, 8], [3, 6, 9], [1, 4, 10], [2, 5, 7], [3, 6, 8], [1, 4, 9], [2, 5, 10], [3, 6, 7], [1, 4, 8], [2, 5, 9], [3, 6, 10], [1, 4, 7], [2, 5, 8], [3, 6, 9], [1, 4, 10], [2, 5, 7], [3, 6, 8], [1, 4, 9], [2, 5, 10], [3, 6, 7], [1, 4, 8], [2, 5, 9], [3, 6, 10]]
0
rnso
from itertools import product 
list_vals = [['Brand Acronym:CBIQ', 'Brand Acronym :KMEFIC'],['Brand Country:DXB','Brand Country:BH']]
list(product(*list_vals))

Sortie:

[('Acronyme de la marque: CBIQ', 'Pays de la marque: DXB'),
('Acronyme de la marque: CBIQ', 'Brand Country: BH'),
('Acronyme de la marque: KMEFIC', 'Brand Country: DXB'),
('Acronyme de la marque: KMEFIC', 'Brand Country: BH')]

0
Kez