2016-07-13 111 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)]