2016-07-13 145 views
0

我有元組的列表:編輯元素

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

如果任何兩個字符串之間的漢明距離小於3,我想加入到合併的元素每個元素的第二個條目。如果上述條件不滿足,我想保持原樣。我想輸出是:

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

我對海明距離的函數:

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)) 

我用下面的列表以識別相關元素進行迭代,但我不知道如何修改原始列表:

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)] 

回答

0

我的假設是,一旦一個元素已被合併,它不需要檢查。我已經添加了三個額外的元素,一個應該匹配,另一個不匹配任何元素,另一個匹配第一個元素(因此有一個元素有多個匹配)可以使測試更穩健一些。

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) 

,其結果是:

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