2013-02-23 10 views
-3

J'ai écrit un programme simple pour traduire l'ADN en ARN. Fondamentalement, vous entrez une chaîne, elle sépare la chaîne en caractères et les envoie à une liste, décale la lettre et renvoie une chaîne de la liste qui en résulte. Ce programme traduit correctement a à, et à a, mais ne change pas g en c et c en g.Comportement étrange en Python

Voici le programme:

def trad(x): 

    h=[] 
    for letter in x: 
     h.append(letter) 
    for letter in h: 
     if letter=="a": 
      h[h.index(letter)]="u" 
      continue 
     if letter=="t": 
      h[h.index(letter)]="a" 
      continue 
     if letter=="g": 
      h[h.index(letter)]="c" 
      continue 
     if letter=="c": 
      h[h.index(letter)]="g" 
      continue 
    ret="" 
    for letter in h: 
     ret+=letter 
    return ret 

while True: 
    stry=raw_input("String?") 
    print trad(stry) 

Maintenant, juste modifier le programme en n'itérer sur les éléments, mais sur des positions, il fonctionne comme prévu. C'est le code qui en résulte:

def trad(x): 
    h=[] 
    for letter in x: 
     h.append(letter) 
    for letter in xrange (0, len(h)): 
     if h[letter]=="a": 
      h[letter]="u" 
      continue 
     if h[letter]=="t": 
      h[letter]="a" 
      continue 
     if h[letter]=="g": 
      h[letter]="c" 
      continue 
     if h[letter]=="c": 
      h[letter]="g" 
      continue 
    ret="" 
    for letter in h: 
     ret+=letter 
    return ret 

while True: 
    stry=raw_input("String?") 
    print trad(stry) 

Pourquoi ce comportement étrange se produit-il, et comment puis-je le résoudre?

+1

Veuillez corriger l'indentation. –

+2

Vous n'expliquez jamais le problème avec votre premier jeu de code. –

+0

Je l'ai édité pour expliquer le problème désolé sur ce –

Répondre

7

Vous allez sur ce beaucoup plus difficile chemin que nécessaire, cela pourrait facilement être fait en utilisant str.translate() - une méthode sur str instances qui se traduit par des instances d'un caractère à l'autre, ce qui est exactement ce que vous voulez:

import string 
replacements = string.maketrans("atgc", "uacg") 
while True: 
    stry=raw_input("String?") 
    print stry.translate(replacements) 

Ceci est une réponse pour 2.x, dans 3.x, utilisez str.maketrans() à la place.

+0

Ce n'est pas seulement plus difficile, c'est beaucoup plus lent que d'utiliser 'translate()'. – martineau

0

Je ne sais pas quel type de problème vous avez, mais voici un moyen simple de le faire, en utilisant un dictionnaire.

def trad(coding_strand): 
    mRNA_parts = {'a': 'u', 't': 'a', 'g': 'c', 'c': 'g'} 
    mRNA = '' 
    for nucleotide in coding_strand: # this makes it lowercase 
     mRNA += mRNA_parts[nucleotide.lower()] 
    return mRNA.upper() # returns it as uppercase 

Je l'ai retourné en majuscules parce que, généralement, les nucléotides dans l'ADN/ARN sont écrits en majuscules.

J'ai également révisé votre méthode ... Il est préférable de parcourir les indices eux-mêmes; alors vous n'avez pas à faire l.index(elem).

def trad(coding_strand): 
    mRNA = [] 
    for index in range(len(coding_strand)): 
     nucleotide = coding_strand[index].upper() 
     if nucleotide == 'A': 
      mRNA.append('U') 
     elif nucleotide == 'T': 
      mRNA.append('A') 
     elif nucleotide == 'C': 
      mRNA.append('G') 
     elif nucleotide == 'G': 
      mRNA.append('C') 
    ret = '' 
    for letter in mRNA: 
     ret += mRNA 
    print ret 

Je ne suggère de ne pas utiliser une chaîne et en ajoutant à elle, ni à l'aide d'une liste; une compréhension de liste est beaucoup plus efficace.

Voici un semi-one-liner, avec la permission de BurhanKhalid:

def trad(coding_strand): 
    mRNA_parts = {'A': 'U', 'T': 'A', 'G': 'C', 'C': 'G'} 
    return ''.join([mRNA_parts[nucleotide] for nucleotide in coding_strand.upper()]) 

Un one-liner complet:

def trade(coding_strand, key={'A': 'U', 'T': 'A', 'G': 'C', 'C': 'G'}): ''.join(return [key[i] for i in coding_strand.upper()]) 

Quelques références:

+0

'return '' .join (mRNA_parts [nucleotide] pour nucleotide dans coding_strand) .upper()' –

+0

@BurhanKhalid J'ai pensé à cela, mais j'ai pensé qu'il était préférable de l'expliquer de manière simple. Je vais inclure cela, cependant. –

+1

Ouais, la construction d'une chaîne par concaténation répétée est sous-optimale et peut causer de graves problèmes de performances sur certaines plates-formes. 'str.join()' et [une compréhension de liste] (http://www.youtube.com/watch?v=pShL9DCSIUw) est une meilleure solution. –