迭代并比较字典中键内的所有值。 Python

时间:2019-03-25 12:44:09

标签: python-3.x

我有一个字典,例如:

dict = {'group1':["-----AGAAC--C--","-----ATATA-----"],'group2':["------AGGCGGA----","--AAACC----------","--AAACCG---------"]}

,在本词典中,我想通过迭代所有值来相互比较所有值。 想法是比较每个值并在字母位于非字母字符前面时计数。

这是我应该得到的结果(在其前面带有非字母字符的字母数(以下示例中的pipe为特征)/字符串的长度)

group1:

element1与element2

-----AGAAC--C--
-----*****--|--
-----ATATA-----
1/15 = 0.07

group2:

元素1与元素2

------AGGCGGA----
--||||*||||||----
--AAACC----------
10/17= 0.59

元素2与元素3

--AAACC----------
--*****|---------
--AAACCG---------
1/17= 0.059

元素1与元素3

------AGGCGGA----
--||||**|||||----
--AAACCG---------
9/17=0.53

这是我用来比较它们并计算第1组得分的代码:

value1="-----AGAAC--C--"
value2="-----ATATA-----"

count=0
for a,b in zip(value1,value2):
    print(a.isalpha(),b.isalpha())
    if a.isalpha() == True and b.isalpha()==False:
        count += 1
    if a.isalpha()==False and b.isalpha()== True :
        count +=1

print(count/len(value1))

但是我无法自动实现所有价值……有人有想法吗? 谢谢您的帮助。

1 个答案:

答案 0 :(得分:2)

这是一种实现方法:

from itertools import combinations

# Input data
dict = {
    'group1': ['-----AGAAC--C--', '-----ATATA-----'],
    'group2': ['------AGGCGGA----', '--AAACC----------', '--AAACCG---------']
}

# Iterate groups
for group, elements in dict.items():
    # Print group name
    print(group)
    # Iterate every pair of elements
    for element1, element2 in combinations(elements, 2):
        # Check both elements have the same length
        n = len(element1)
        if len(element2) != n:
            raise ValueError
        # Count the number of times character types do not match
        count = sum(c1.isalpha() != c2.isalpha() for c1, c2 in zip(element1, element2))
        # Compute ratio
        ratio = count / n
        # Print result
        print(f'    * {element1} vs {element2}: {ratio:.4f} ({count}/{n})')
    print()

输出:

group1
    * -----AGAAC--C-- vs -----ATATA-----: 0.0667 (1/15)

group2
    * ------AGGCGGA---- vs --AAACC----------: 0.5882 (10/17)
    * ------AGGCGGA---- vs --AAACCG---------: 0.5294 (9/17)
    * --AAACC---------- vs --AAACCG---------: 0.0588 (1/17)

编辑:如果要收集对得分高于某个阈值的对的列表,可以略微修改上面的代码:

from itertools import combinations

dict = {
    'group1': ['-----AGAAC--C--', '-----ATATA-----'],
    'group2': ['------AGGCGGA----', '--AAACC----------', '--AAACCG---------']
}
threshold = 0.10

interesting_pairs = []
for group, elements in dict.items():
    for element1, element2 in combinations(elements, 2):
        n = len(element1)
        if len(element2) != n:
            raise ValueError
        count = sum(c1.isalpha() != c2.isalpha() for c1, c2 in zip(element1, element2))
        ratio = count / n
        if ratio > threshold:
            interesting_pairs.append((element1, element2))

print(interesting_pairs)
# [('------AGGCGGA----', '--AAACC----------'), ('------AGGCGGA----', '--AAACCG---------')]

编辑2:在评论中进行讨论之后,这是又一个变体,将具有一定阈值以上比率的元素可传递地组合在一起。实际上,这本身就是另一个不同的问题,即找到由该关系给出的图的connected components。您可以通过深度优先搜索来做到这一点:

from itertools import combinations

dict = {
    'group1': ['-----AGAAC--C--', '-----ATATA-----'],
    'group2': ['------AGGCGGA----', '--AAACC----------', '--AAACCG---------']
}
threshold = 0.10

# Find connected elements
connected = {}
for group, elements in dict.items():
    for element1, element2 in combinations(elements, 2):
        n = len(element1)
        if len(element2) != n:
            raise ValueError
        count = sum(c1.isalpha() != c2.isalpha() for c1, c2 in zip(element1, element2))
        ratio = count / n
        if ratio > threshold:
            connected.setdefault(element1, {element1}).add(element2)
            connected.setdefault(element2, {element2}).add(element1)

# Search components with DFS
result = []
visited = set()
for elem, conn in  connected.items():
    if elem in visited:
        continue
    visited.add(elem)
    conn = set(conn)
    pending = list(conn)
    while pending:
        subelem = pending.pop()
        if subelem in visited:
            continue
        visited.add(subelem)
        subconn = connected[subelem]
        conn.update(subconn)
        pending.extend(subconn)
    result.append(conn)
print(result)
# [{'------AGGCGGA----', '--AAACCG---------', '--AAACC----------'}]