2012-01-18 1 views
2

testant la correspondance exacte des chaînes de caractères dans les chaînes cibles. la sortie doit être un tuple des points de départ des correspondances. Mon code fonctionne mais j'ai l'impression qu'il peut être beaucoup plus propre. Comment est-ce que je pourrais retourner un tuple sans convertir à partir d'une liste ajoutée? cherché partout et ne peut pas sembler trouver une réponse. Merci!!Python For loop return Tuple - existe-t-il une meilleure façon de faire cela

from string import * 


target1 = 'atgacatgcacaagtatgcat' 
target2 = 'atgaatgcatggatgtaaatgcag' 

key10 = 'a' 
key11 = 'atg' 
key12 = 'atgc' 
key13 = 'atgca' 

def subStringMatchExact(target, key): 
    match_list = [] 
    location = 0 

    for i in target: 
     ans = find(target, key, location) 
     if ans >= 0: 
      match_list.append(ans) 
      location = ans + (len(key)) 

    print tuple(match_list) 

subStringMatchExact(target1, key11) 
+1

Tuples ne sont pas mutable, donc si vous créez à la volée , ça doit être une liste. Vous ne savez pas pourquoi vous pensez que le code est "pas propre" parce que vous devez convertir en un tuple? – Chip

+0

Copie possible: http://stackoverflow.com/questions/4664850/find-all-occurrences-of-a-substring-in-python – Krumelur

Répondre

1

Ceci est un travail parfait pour les expressions régulières.

import re 
def subStringMatchExact(target, key): 
    regex = re.compile(re.escape(key)) 
    return tuple(match.start() for match in regex.finditer(target)) 

Notez que ceci trouve seulement des correspondances qui ne se chevauchent pas. Si vous voulez trouver des correspondances qui se chevauchent aussi:

def subStringMatchExact(target, key): 
    regex = re.compile("(?=" + re.escape(key) + ")") 
    return tuple(match.start() for match in regex.finditer(target)) 

Bien sûr, à moins que vous avez réellement besoin que le résultat soit un tuple, vous pouvez simplement supprimer le tuple de la dernière ligne et que votre fonction retourne un générateur plus efficace .

+0

Merci Tim! Je vais certainement étudier sur regex. – Leerix

+0

Cela ne me dérange pas le downvote, mais je suis curieux de savoir pourquoi. Toute explication? –

+0

Cela peut être un accident ou parce que quelqu'un considère que cette question est un doublon (la question est aussi faussement downvoted (les doublons doivent être fermés, pas downvoted)). J'ai rencontré des cas où toutes les réponses sont downvoted (mais pas dans ce cas). Je considère cette question sur la façon d'obtenir un «tuple» sans créer une liste intermédiaire, donc ce n'est pas une copie exacte. – jfs

1
def subStringMatchExact(target, key): 
    i = target.find(key) 
    while i != -1: 
     yield i 
     i = target.find(key, i + len(key)) 

print tuple(subStringMatchExact(target1, key11)) 

BTW, ne pas utiliser ces noms comme target1, key11 utilisation targets, keys listes à la place.

0

Voici une autre façon de le faire:

def find_sublist(l, sublist): 
    for i in xrange(len(l)-len(sublist)+1): 
     if sublist == l[i:i+len(sublist)]: 
      yield i 

alors vous pouvez faire quelque chose comme ça pour obtenir votre tuple:

tuple(find_sublist(target1, key11))