2016-04-30 1 views
2

J'essaie de mettre en place un code qui remplace les caractères uniques dans une chaîne d'entrée donnée par des valeurs correspondantes dans un dictionnaire de manière combinatoire tout en préservant la position des caractères 'non' uniques.Permutations utilisant un multidict

Par exemple, je dois le dictionnaire suivant:

d = {'R':['A','G'], 'Y':['C','T']} 

Comment s'y prendrait pour remplacer toutes les occurrences de « R » et « Y » tout en produisant toutes les combinaisons possibles de la chaîne, mais maintenant les positions de « A ' et C'?

Par exemple, l'entrée 'ARCY' générerait la sortie suivante:

'AACC' 
'AGCC' 
'AACT' 
'AGCT' 

Espérons que logique. Si quelqu'un peut me pointer dans les bonnes directions, ce serait génial!

+2

Utiliser 'str.replace' de remplacer les caractères et [' itertools.permutations'] (https://docs.python.org/3.5/library/itertools.html#itertools.permutations) pour les permutations. – ChrisP

+0

Par unique, voulez-vous dire que nous voyons seulement R et Y une fois dans l'entrée? – ayhan

+0

Unique en ce sens que les caractères tels que R et Y sont remplacés par des valeurs multiples alors que tout reste tel quel. – moj

Répondre

1

Ce qui suit generator function produit toutes vos chaînes désirées, en utilisant enumerate, zip, itertools.product, un list comprehension et argument list unpacking tous sont très utiles Python outils/concepts que vous devriez lire sur:

from itertools import product 

def multi_replace(s, d): 
    indexes, replacements = zip(*[(i, d[c]) for i, c in enumerate(s) if c in d]) 
    # indexes: (1, 3) 
    # replacements: (['A', 'G'], ['C', 'T']) 

    l = list(s) # turn s into sth. mutable 
    # iterate over cartesian product of all replacement tuples ... 
    for p in product(*replacements): 
     for index, replacement in zip(indexes, p): 
      l[index] = replacement 
     yield ''.join(l) 

d = {'R': ['A', 'G'], 'Y': ['C', 'T']} 
s = 'ARCY' 

for perm in multi_replace(s, d): 
    print perm 

AACC 
AACT 
AGCC 
AGCT 

s = 'RRY' 

AAC 
AAT 
AGC 
AGT 
GAC 
GAT 
GGC 
GGT 
+0

Génial! Cela fonctionne très bien, merci. – moj

0

changement ARCY à la liste multiple et utiliser ci-dessous le code:

import itertools as it 
list = [['A'], ['A','G'],['C'],['C','T']] 
[''.join(item) for item in it.product(*list)] 

ou

import itertools as it 
list = ['A', 'AG','C', 'CT'] 
[''.join(item) for item in it.product(*list)] 
+0

Existe-t-il un moyen de récupérer les valeurs d'un dictionnaire au lieu de l'énumérer? Si j'élargis l'entrée pour dire 15 caractères, cette méthode deviendrait très fastidieuse. – moj

+0

Prendre une liste vide, puis itérer chaque caractère de la chaîne d'entrée et vérifier si la clé (chaque caractère) existe dans le dictionnaire et ajouter la valeur à votre liste initiale si correspondance trouvée, sinon ajouter [caractère actuel] à votre liste initiale. Cela ne sera pas fastidieux même si la longueur de la chaîne d'entrée est élevée. –