2016-07-13 16 views
0

ich eine Liste von Tupeln habe:Bearbeiten von Elementen einer Liste von Tupeln basierend auf Hammingabstands

f_list = [('AGCTCCCCGTTTTC', 34), ('TTCATTCCTCTCTC', 1), ('AGCTCCCCGGTTTC', 1)] 

Wenn die Hamming-Distanz zwischen zwei Strings weniger als 3, würde Ich mag die Elemente verschmelzen durch Hinzufügen die zweiten Einträge jedes Elements. Wenn die obige Bedingung nicht erfüllt ist, möchte ich das Element beibehalten wie es ist. Der Ausgang ich will, ist:

f_list = [('AGCTCCCCGTTTTC', 35),('TTCATTCCTCTCTC', 1)] 

ich die Funktion für Hamming-Distanz haben:

def hamming(s1, s2): 
    if len(s1) != len(s2): 
    raise ValueError("Undefined for sequences of unequal length") 
return sum(ch1 != ch2 for ch1, ch2 in zip(s1, s2)) 

benutzte ich die folgenden durch die Liste zu durchlaufen die entsprechenden Elemente zu identifizieren, doch bin ich nicht sicher, wie man Ändern Sie die ursprüngliche Liste:

for e in f_list: 
    [item for item in f_list if hamming(e[0],item[0]) < 3] 

Output: 
[('AGCTCCCCGTTTTC', 34), ('AGCTCCCCGGTTTC', 1)] 
[('TTCATTCCTCTCTC', 1)] 
[('AGCTCCCCGTTTTC', 34), ('AGCTCCCCGGTTTC', 1)] 

Antwort

0

Meine Annahmen sind, dass, sobald ein Element zusammengeführt wurde, es nicht überprüft werden muss. Ich habe drei zusätzliche Elemente hinzugefügt, eins, das übereinstimmen sollte und ein anderes, das nicht mit einem übereinstimmt, und eins, das dem ersten Element entspricht (also ein Element, das mehr als eine Übereinstimmung hat), um den Test ein wenig robuster zu machen .

import itertools # we'll use islice in case dataset is large and limited memory 

def hamming(s1, s2): 
    if len(s1) != len(s2): 
     raise ValueError("Undefined for sequences of unequal length") 
    return sum(ch1 != ch2 for ch1, ch2 in zip(s1, s2))  


f_list = [('AGCTCCCCGTTTTC', 34), ('TTCATTCCTCTCTC', 1), ('GGGGCCCCCAAAAA', 99), 
      ('TGCATTCCTATCTC', 8), ('AGCTCCCCGGTTTC', 1), ('AGCTCCCCGTCTTC', 100)] 


def merge_elements(f_list): 
    result = [] 
    flag = [True for _ in f_list] 

    for i, seq1 in enumerate(f_list): 
     none_close = True 
     total = seq1[1] 
     for j, seq2 in enumerate(itertools.islice(f_list, i+1, len(f_list))): 
      if flag[i+j+1] and hamming(seq1[0],seq2[0]) < 3: 
       total += seq2[1] 
       none_close = False 
       flag[j+i+1] = False 
     if flag[i] and none_close: 
      result.append(seq1) 
     elif flag[i]: 
      result.append((seq1[0],total)) 
    return result 


f_list = merge_elements(f_list) 
print(f_list) 

Und das Ergebnis ist:

[('AGCTCCCCGTTTTC', 135), ('TTCATTCCTCTCTC', 9), ('GGGGCCCCCAAAAA', 99)] 
Verwandte Themen