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 partie la plus délicate est que je pourrais avoir plus d'éléments dans la variable «nom» que d'éléments dans la variable «nombre» (le nombre sera toujours égal ou inférieur à la variable nom).
Je ne sais pas comment faire toutes les combinaisons (imbriquées pour la boucle?) Et encore plus confus sur la logique pour déplacer les éléments dans la variable de nom dans le cas où il y aurait plus d'éléments dans le nom qu'ils ne le sont dans la liste de numéros.
Je ne suis pas le meilleur programmeur, mais je pense que je peux essayer si quelqu'un peut m'aider à clarifier la logique / algorithme pour y parvenir. Je viens donc d'être bloqué sur des boucles for imbriquées.
Mise à jour:
Voici la sortie avec 3 variables et 2 nombres:
name = 'a', 'b', 'c'
number = 1, 2
production:
1. A1 B2
2. B1 A2
3. A1 C2
4. C1 A2
5. B1 C2
6. C1 B2
la source
Réponses:
Remarque : Cette réponse concerne la question spécifique posée ci-dessus. Si vous êtes ici de Google et que vous cherchez simplement un moyen d'obtenir un produit cartésien en Python,
itertools.product
ou une simple compréhension de liste peut être ce que vous recherchez - voir les autres réponses.Supposons
len(list1) >= len(list2)
. Alors ce que vous semblez vouloir est de prendre toutes les permutations de longueurlen(list2)
delist1
et les jumeler avec des articles de liste2. En python:import itertools list1=['a','b','c'] list2=[1,2] [list(zip(x,list2)) for x in itertools.permutations(list1,len(list2))]
Retour
[[('a', 1), ('b', 2)], [('a', 1), ('c', 2)], [('b', 1), ('a', 2)], [('b', 1), ('c', 2)], [('c', 1), ('a', 2)], [('c', 1), ('b', 2)]]
la source
zip
et similaire.Le moyen le plus simple est d'utiliser
itertools.product
:a = ["foo", "melon"] b = [True, False] c = list(itertools.product(a, b)) >> [("foo", True), ("foo", False), ("melon", True), ("melon", False)]
la source
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] # for a list [('foo', 1), ('foo', 2), ('foo', 3), ('bar', 1), ('bar', 2), ('bar', 3)] >>> ((x,y) for x in a for y in b) # for a generator if you worry about memory or time complexity. <generator object <genexpr> at 0x1048de850>
sans aucune importation
la source
Je cherchais une liste multipliée par elle-même avec uniquement des combinaisons uniques, qui est fournie comme cette fonction.
import itertools itertools.combinations(list, n_times)
Voici un extrait de la documentation Python sur
itertools
Cela pourrait vous aider à trouver ce que vous cherchez.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
la source
Vous voudrez peut-être essayer une compréhension de 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']
la source
la meilleure façon de découvrir 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')]
la source
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 donc les performances ne sont déjà pas votre principale préoccupation ...
J'aime aussi toutes les autres réponses!
la source
une petite amélioration pour la réponse de l'interjay, pour rendre le résultat comme une 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 à partir de ce lien
la source
Sans itertools
[(list1[i], list2[j]) for i in xrange(len(list1)) for j in xrange(len(list2))]
la source
En répondant à la question "étant donné deux listes, trouvez toutes les permutations possibles de paires d'un élément de chaque liste" et en utilisant les fonctionnalités de base de Python (c'est-à-dire sans itertools) et, par conséquent, en facilitant la réplication pour d'autres langages de programmation:
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)
Retour
[['a1', 'b2'], ['a1', 'c2'], ['a2', 'b1'], ['a2', 'c1'], ['b1', 'c2'], ['b2', 'c1']]
la source
Les meilleures réponses à cela ne fonctionnent que pour des longueurs spécifiques de listes fournies.
Voici une version qui fonctionne pour toutes les longueurs d'entrée. Cela rend également l'algorithme clair 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 produit:
0: A1 B2 1: A1 C2 2: B1 A2 3: B1 C2 4: C1 A2 5: C1 B2
la source