2017-08-31 4 views
3

Dire que j'ai une liste de chaînes:Génération toutes les combinaisons possibles de caractères dans une chaîne

li = ['a', 'b', 'c'] 

je voudrais construire une nouvelle liste de telle sorte que chaque entrée de la nouvelle liste est une concaténation d'une sélection de 3 entrées dans la liste d'origine. Notez que chaque entrée peut être choisie de manière répétée:

new_li=['abc', 'acb', 'bac', 'bca', 'cab', 'cba', 'aab', 'aac',....'aaa', 'bbb', 'ccc'] 

La voie de la force brutale est de construire une 3 fois imbriqués pour chaque boucle et insérer 3-combinaison dans la nouvelle liste. Je me demandais s'il y avait une façon de Python de faire face à cela? Merci.

Mise à jour: Plus tard, je vais convertir la nouvelle liste en un ensemble, de sorte que l'ordre n'a pas d'importance quand même.

+0

Faut-il que ce soit aléatoire? Combien de temps devrait être la liste? –

+0

@ whackamadoodle3000 S'il vous plaît voir les mises à jour. La longueur de la liste devrait être 3^n, où n est le nombre d'entrées dans la liste originale – James

Répondre

3

Cela ressemble à un travail pour itertools.product.

import itertools 

def foo(l): 
    yield from itertools.product(*([l] * 3)) 

for x in foo('abc'): 
    print(''.join(x)) 

aaa 
aab 
aac 
aba 
abb 
abc 
aca 
acb 
acc 
baa 
bab 
bac 
bba 
bbb 
bbc 
bca 
bcb 
bcc 
caa 
cab 
cac 
cba 
cbb 
cbc 
cca 
ccb 
ccc 

yield from est à votre disposition de python3.3 et au-delà. Pour une version plus ancienne, yield dans une boucle:

def foo(l): 
    for i in itertools.product(*([l] * 3)) : 
     yield i 
+0

Merci. Que se passe-t-il si chaque entrée de la liste d'origine n'est pas un seul caractère, comme li = ['a1', 'b2', 'c3']? – James

+1

@James Cela fonctionne exactement de la même manière. Tu pourrais juste l'essayer. –

1

La meilleure façon d'obtenir toutes les combinaisons (aussi appelé produit cartésien) d'une liste est d'utiliser itertools.product en utilisant la len de votre itérables comme argument repeat (c'est où il se distingue de l'autre réponse):

from itertools import product 
li = ['a', 'b', 'c'] 
for comb in product(li, repeat=len(li)): 
    print(''.join(comb)) 

ou si vous voulez que le résultat liste:

>>> combs = [''.join(comb) for comb in product(li, repeat=len(li))] 
>>> combs 
['aaa', 'aab', 'aac', 'aba', 'abb', 'abc', 'aca', 'acb', 'acc', 'baa', 
'bab', 'bac', 'bba', 'bbb', 'bbc', 'bca', 'bcb', 'bcc', 'caa', 'cab', 
'cac', 'cba', 'cbb', 'cbc', 'cca', 'ccb', 'ccc'] 

Il est un peu plus propre d'utiliser l'argument repeat que de multiplier et décompresser la liste que vous avez manuellement.