我有一个元组列表:
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 :(得分: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)]