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
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)]]
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)]
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
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
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']
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
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']]
Sans outils informatiques
[(list1[i], list2[j]) for i in xrange(len(list1)) for j in xrange(len(list2))]
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!
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')]
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