web-dev-qa-db-fra.com

Python fusionnant deux listes avec toutes les permutations possibles

J'essaie de trouver le meilleur moyen de fusionner deux listes en toutes les combinaisons possibles. Donc, si je commence avec deux listes comme celle-ci:

list1 = [1, 2]
list2 = [3, 4]

La liste résultante ressemblera à ceci:

[[[1,3], [2,4]], [[1,4], [2,3]]]

En d’autres termes, il produit essentiellement une liste de listes, avec toutes les combinaisons possibles entre les deux.

J'ai passé en revue les outils informatiques, ce dont je suis sûr, présume la réponse, mais je ne peux pas trouver un moyen de le faire agir ainsi. Le plus proche je suis venu était:

list1 = [1, 2, 3, 4]
list2 = [5, 6, 7, 8]
print list(itertools.product(list1, list2))

Qui a produit:

[(1, 5), (1, 6), (1, 7), (1, 8), (2, 5), (2, 6), (2, 7), (2, 8), (3, 5), (3, 6), (3, 7), (3, 8), (4, 5), (4, 6), (4, 7), (4, 8)]

Donc, il fait toutes les combinaisons possibles d'éléments dans chaque liste, mais pas toutes les listes résultantes possibles. Comment puis-je arriver à cela?

EDIT: L’objectif final est de pouvoir traiter individuellement chaque liste afin de déterminer son efficacité (les données réelles avec lesquelles je travaille sont plus complexes). Ainsi, dans l'exemple original ci-dessus, cela fonctionnerait comme ceci:

list1 = [1, 2]
list2 = [3, 4]

Get first merged list: [[1,3], [2, 4]]
    Do stuff with this list
Get second merged list: [[1,4], [2, 3]]
    Do stuff with this list

Si je obtenais la sortie "liste de listes de listes" décrite ci-dessus, je pourrais la placer dans une boucle for et la traiter. D'autres formes de production fonctionneraient, mais cela semble être le plus simple.

15
GeoJunkie

repeat la première liste, permutate la deuxième et Zip tout ensemble

>>> from itertools import permutations, repeat
>>> a = [1, 2, 3]
>>> b = [4, 5, 6]
>>> list(list(Zip(r, p)) for (r, p) in Zip(repeat(a), permutations(b)))
[[(1, 4), (2, 5), (3, 6)],
 [(1, 4), (2, 6), (3, 5)],
 [(1, 5), (2, 4), (3, 6)],
 [(1, 5), (2, 6), (3, 4)],
 [(1, 6), (2, 4), (3, 5)],
 [(1, 6), (2, 5), (3, 4)]]

EDIT: Comme l'a noté Peter Otten, la Zip intérieure et la repeat sont superflues.

[list(Zip(a, p)) for p in permutations(b)]
19
pacholik

La réponse acceptée peut être simplifiée pour

a = [1, 2, 3]
b = [4, 5, 6]
[list(Zip(a, p)) for p in permutations(b)]

(L'appel list () peut être omis dans Python 2)

10
Peter Otten

Essayez d’utiliser le générateur de liste pour créer les listes imbriquées:

>>> [[[x,y] for x in list1] for y in list2]
[[[1, 3], [2, 3]], [[1, 4], [2, 4]]]
>>>

Ou, si vous voulez une liste sur une ligne, supprimez simplement les crochets:

>>> [[x,y] for x in list1 for y in list2]
[[1, 3], [1, 4], [2, 3], [2, 4]]
8
Sdwdaw

Edité mon code pour vous donner votre sortie désirée. 

list1 = [1,2]
list2 = [3,4]
combined = []

for a in list1:
    new_list = []
    for b in list2:
        new_list.append([a, b])
    combined.append(new_list)

print combined
3
Joe Smart

Vous pouvez créer une liste en construisant toutes les permutations de deux membres de la liste avec celle-ci, contenant les combinaisons de liste.

lst1 = [1,2]
lst2 = [3,4]

#lst = [[j,k] for j in lst1 for k in lst2] # [[1,3],[1,4],[2,3],[2,4]]
lst = [[[j,k] for j in lst1] for k in lst2] # [[[1,3],[2,3]],[[1,4],[2,4]]]
print lst
2
Semih Yagcioglu

Essaye ça:

combos=[]
for i in list1:
      for j in list2:
          combos.append([i,j])
print combos
1
pydude

Comme la réponse de @pacholik ne couvre pas les listes de longueur différente, voici ma solution, utilisant une compréhension de liste avec deux variables:

first_list = [1, 2, 3]
second_list = ['a', 'b']

combinations = [(a,b) for a in first_list for b in second_list]

La sortie ressemble à ceci:

[(1, 'a'), (1, 'b'), (2, 'a'), (2, 'b'), (3, 'a'), (3, 'b')]
1
Minato