web-dev-qa-db-fra.com

combinaisons entre deux listes?

Cela fait un moment et j’ai du mal à comprendre un algorithme que j’essaie de créer. En gros, j'ai deux listes et je veux obtenir toutes les combinaisons des deux listes.

Je ne l’explique peut-être pas correctement, alors voici un exemple.

name = 'a', 'b'
number = 1, 2

la sortie dans ce cas serait:

1.  A1 B2
2.  B1 A2

La difficulté réside dans le fait que je pourrais avoir plus d’éléments dans la variable "name" que d’éléments dans la variable "number" (le nombre sera toujours égal ou inférieur à la variable name).

Je ne comprends pas comment faire toutes les combinaisons (imbriquées pour la boucle?) Et encore plus dans la logique qui consiste à décaler les éléments de la variable name au cas où il y aurait plus d'éléments dans le nom que dans la liste de numéros.

Je ne suis pas le meilleur programmeur, mais je pense pouvoir tenter le coup si quelqu'un peut m'aider à clarifier la logique/algorithme pour y parvenir. Donc, je viens d'être coincé sur des boucles imbriquées.

Mise à jour:

Voici la sortie avec 3 variables et 2 nombres:

name = 'a', 'b', 'c'
number = 1, 2

sortie:

1.  A1 B2
2.  B1 A2
3.  A1 C2
4.  C1 A2
5.  B1 C2
6.  C1 B2
143
user1735075

Supposons que len(list1) >= len(list2). Ensuite, ce que vous semblez vouloir est de prendre toutes les permutations de longueur len(list2) de list1 et de les faire correspondre aux éléments de list2. En python:

import itertools
list1=['a','b','c']
list2=[1,2]

[Zip(x,list2) for x in itertools.permutations(list1,len(list2))]

Résultats

[[('a', 1), ('b', 2)], [('a', 1), ('c', 2)], [('b', 1), ('a', 2)], [('b', 1), ('c', 2)], [('c', 1), ('a', 2)], [('c', 1), ('b', 2)]]
71
interjay

Le moyen le plus simple consiste à utiliser itertools.product:

a = ["foo", "melon"]
b = [True, False]
c = list(itertools.product(a, b))
>> [("foo", True), ("foo", False), ("melon", True), ("melon", False)]
406
DrIDK

Peut-être plus simple que le plus simple ci-dessus:

>>> a = ["foo", "bar"]
>>> b = [1, 2, 3]
>>> [(x,y) for x in a for y in b]
[('foo', 1), ('foo', 2), ('foo', 3), ('bar', 1), ('bar', 2), ('bar', 3)]

sans aucune importation

126
logic

Je cherchais une liste multipliée par elle-même avec seulement des combinaisons uniques, qui est fournie comme cette fonction.

import itertools
itertools.combinations(list, n_times)

Voici un extrait de le Python docs sur itertools Cela pourrait vous aider à trouver ce que vous recherchez.

Combinatoric generators:

Iterator                                 | Results
-----------------------------------------+----------------------------------------
product(p, q, ... [repeat=1])            | cartesian product, equivalent to a 
                                         |   nested for-loop
-----------------------------------------+----------------------------------------
permutations(p[, r])                     | r-length tuples, all possible 
                                         |   orderings, no repeated elements
-----------------------------------------+----------------------------------------
combinations(p, r)                       | r-length tuples, in sorted order, no 
                                         |   repeated elements
-----------------------------------------+----------------------------------------
combinations_with_replacement(p, r)      | r-length tuples, in sorted order, 
                                         | with repeated elements
-----------------------------------------+----------------------------------------
product('ABCD', repeat=2)                | AA AB AC AD BA BB BC BD CA CB CC CD DA DB DC DD
permutations('ABCD', 2)                  | AB AC AD BA BC BD CA CB CD DA DB DC
combinations('ABCD', 2)                  | AB AC AD BC BD CD
combinations_with_replacement('ABCD', 2) | AA AB AC AD BB BC BD CC CD DD
16
ThorSummoner

Vous voudrez peut-être essayer une compréhension d'une liste en une ligne:

>>> [name+number for name in 'ab' for number in '12']
['a1', 'a2', 'b1', 'b2']
>>> [name+number for name in 'abc' for number in '12']
['a1', 'a2', 'b1', 'b2', 'c1', 'c2']
11
Idanmel

une petite amélioration pour la réponse d'interjay, pour faire le résultat sous forme de liste aplatie.

>>> list3 = [Zip(x,list2) for x in itertools.permutations(list1,len(list2))]
>>> import itertools
>>> chain = itertools.chain(*list3)
>>> list4 = list(chain)
[('a', 1), ('b', 2), ('a', 1), ('c', 2), ('b', 1), ('a', 2), ('b', 1), ('c', 2), ('c', 1), ('a', 2), ('c', 1), ('b', 2)]

référence de cette lien

9
Mass Zhou

En répondant à la question "à partir de deux listes, trouvez toutes les permutations possibles des paires d'un élément de chaque liste" et utilisez la fonctionnalité de base Python (c'est-à-dire sans ses outils) pour faciliter la réplication pour une autre programmation. langues:

def rec(a, b, ll, size):
    ret = []
    for i,e in enumerate(a):
        for j,f in enumerate(b):
            l = [e+f]
            new_l = rec(a[i+1:], b[:j]+b[j+1:], ll, size)
            if not new_l:
                ret.append(l)
            for k in new_l:
                l_k = l + k
                ret.append(l_k)
                if len(l_k) == size:
                    ll.append(l_k)
    return ret

a = ['a','b','c']
b = ['1','2']
ll = []
rec(a,b,ll, min(len(a),len(b)))
print(ll)

Résultats

[['a1', 'b2'], ['a1', 'c2'], ['a2', 'b1'], ['a2', 'c1'], ['b1', 'c2'], ['b2', 'c1']]
4
computerist

Sans outils informatiques

[(list1[i], list2[j]) for i in xrange(len(list1)) for j in xrange(len(list2))]
4
user3684792

Ou la réponse KISS pour les listes courtes:

[(i, j) for i in list1 for j in list2]

Pas aussi performant que itertools, mais vous utilisez python, les performances ne sont donc déjà plus votre principal souci ...

J'aime toutes les autres réponses aussi!

3
Fletch F Fletch

le meilleur moyen de connaître toutes les combinaisons pour un grand nombre de listes est:

import itertools
from pprint import pprint

inputdata = [
    ['a', 'b', 'c'],
    ['d'],
    ['e', 'f'],
]
result = list(itertools.product(*inputdata))
pprint(result)

le résultat sera:

[('a', 'd', 'e'),
 ('a', 'd', 'f'),
 ('b', 'd', 'e'),
 ('b', 'd', 'f'),
 ('c', 'd', 'e'),
 ('c', 'd', 'f')]
1
Ishan Rastogi

Les meilleures réponses à cette question ne fonctionnent que pour des longueurs spécifiques de listes fournies.

Voici une version qui fonctionne pour toutes les longueurs d’entrée. Cela clarifie également l'algorithme en termes de concepts mathématiques de combinaison et de permutation.

from itertools import combinations, permutations
list1 = ['1', '2']
list2 = ['A', 'B', 'C']

num_elements = min(len(list1), len(list2))
list1_combs = list(combinations(list1, num_elements))
list2_perms = list(permutations(list2, num_elements))
result = [
  Tuple(Zip(perm, comb))
  for comb in list1_combs
  for perm in list2_perms
]

for idx, ((l11, l12), (l21, l22)) in enumerate(result):
  print(f'{idx}: {l11}{l12} {l21}{l22}')

Cela génère:

0: A1 B2
1: A1 C2
2: B1 A2
3: B1 C2
4: C1 A2
5: C1 B2
1
Steve Alexander