根据汉明距离编辑元组列表的元素

时间:2016-07-13 02:23:21

标签: python

我有一个元组列表:

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

1 个答案:

答案 0 :(得分: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)]