Python 在一个键下有多个值的字典中检索顶级值

Python 在一个键下有多个值的字典中检索顶级值,python,dictionary,Python,Dictionary,我对python有些陌生,我有一个问题。 我有一个文件,每个唯一标识符有5个结果。每个结果都有一个匹配百分比和其他各种数据段。我的目标是找到匹配百分比最大的结果,然后从原始行检索更多信息。 比如说 Name Organism Percent Match Misc info 1 Human 100 xxx 1 Goat 95 yyy 1 Pig

我对python有些陌生,我有一个问题。 我有一个文件,每个唯一标识符有5个结果。每个结果都有一个匹配百分比和其他各种数据段。我的目标是找到匹配百分比最大的结果,然后从原始行检索更多信息。 比如说

Name    Organism    Percent Match     Misc info
1        Human        100              xxx     
1        Goat          95              yyy
1        Pig           90              zzz   
我试图解决这个问题,将每个键放入一个字典中,每个值都是给定名称唯一的匹配百分比,即每个键都有多个值。我认为继续的唯一方法是将此字典中的值转换为列表,然后对列表进行排序。然后,我要检索列表[0]或列表[-1]中的最大值,然后从原始行检索更多信息。 这是到目前为止我的代码

list = []  
if "1" in line: 
    id = line
    bsp = id.split("\t")
    uid = bsp[0]
    per = bsp[2]

    if not dict.has_key(uid):
        dict[uid] = []
    dict[uid].append(per)
    list = dict[uid]
    list.sort()
if list[0] in dict:
    print key

最终只打印每个键,而不是只打印百分比最大的键。有什么想法吗?谢谢

您应该能够执行以下操作:

lines = []
with open('data.txt') as file:
    for line in file:
        if line.startswith('1'):
            lines.append(line.split())

best_match = max(lines, key=lambda k: int(k[2]))
>>> pprint.pprint(lines)
[['1', 'Human', '100', 'xxx'],
 ['1', 'Goat', '95', 'yyy'],
 ['1', 'Pig', '90', 'zzz']]
>>> max(lines, key=lambda k: int(k[2]))
['1', 'Human', '100', 'xxx']
读取文件后,文件行将如下所示:

lines = []
with open('data.txt') as file:
    for line in file:
        if line.startswith('1'):
            lines.append(line.split())

best_match = max(lines, key=lambda k: int(k[2]))
>>> pprint.pprint(lines)
[['1', 'Human', '100', 'xxx'],
 ['1', 'Goat', '95', 'yyy'],
 ['1', 'Pig', '90', 'zzz']]
>>> max(lines, key=lambda k: int(k[2]))
['1', 'Human', '100', 'xxx']
然后从第三项的int值最高的行中获取条目,可以这样表示:

lines = []
with open('data.txt') as file:
    for line in file:
        if line.startswith('1'):
            lines.append(line.split())

best_match = max(lines, key=lambda k: int(k[2]))
>>> pprint.pprint(lines)
[['1', 'Human', '100', 'xxx'],
 ['1', 'Goat', '95', 'yyy'],
 ['1', 'Pig', '90', 'zzz']]
>>> max(lines, key=lambda k: int(k[2]))
['1', 'Human', '100', 'xxx']
因此,在这个最佳匹配的末尾将是一个列表,其中包含您感兴趣的行中的数据

或者,如果你想变得非常棘手,你可以通过一个复杂的步骤来完成:

with open('data.txt') as file:
    best_match = max((s.split() for s in file if s.startswith('1')),
                     key=lambda k: int(k[2]))

您应该能够执行以下操作:

lines = []
with open('data.txt') as file:
    for line in file:
        if line.startswith('1'):
            lines.append(line.split())

best_match = max(lines, key=lambda k: int(k[2]))
>>> pprint.pprint(lines)
[['1', 'Human', '100', 'xxx'],
 ['1', 'Goat', '95', 'yyy'],
 ['1', 'Pig', '90', 'zzz']]
>>> max(lines, key=lambda k: int(k[2]))
['1', 'Human', '100', 'xxx']
读取文件后,文件行将如下所示:

lines = []
with open('data.txt') as file:
    for line in file:
        if line.startswith('1'):
            lines.append(line.split())

best_match = max(lines, key=lambda k: int(k[2]))
>>> pprint.pprint(lines)
[['1', 'Human', '100', 'xxx'],
 ['1', 'Goat', '95', 'yyy'],
 ['1', 'Pig', '90', 'zzz']]
>>> max(lines, key=lambda k: int(k[2]))
['1', 'Human', '100', 'xxx']
然后从第三项的int值最高的行中获取条目,可以这样表示:

lines = []
with open('data.txt') as file:
    for line in file:
        if line.startswith('1'):
            lines.append(line.split())

best_match = max(lines, key=lambda k: int(k[2]))
>>> pprint.pprint(lines)
[['1', 'Human', '100', 'xxx'],
 ['1', 'Goat', '95', 'yyy'],
 ['1', 'Pig', '90', 'zzz']]
>>> max(lines, key=lambda k: int(k[2]))
['1', 'Human', '100', 'xxx']
因此,在这个最佳匹配的末尾将是一个列表,其中包含您感兴趣的行中的数据

或者,如果你想变得非常棘手,你可以通过一个复杂的步骤来完成:

with open('data.txt') as file:
    best_match = max((s.split() for s in file if s.startswith('1')),
                     key=lambda k: int(k[2]))
您可以使用csv解析选项卡描述的数据文件,尽管您发布的数据看起来是以列为间隔的数据

由于数据文件中的第一行给出了字段名,因此DictReader非常方便,因此您可以通过人类可读的名称来引用列

csv.DictReader返回一个dicts行的iterable。如果使用“匹配百分比”列作为键获取iterable的最大值,则可以找到匹配百分比最高的行:

将此选项卡分隔的数据用作test.dat:

节目

import csv

maxrows = {}
with open('test.dat', 'rb') as f:
    for row in csv.DictReader(f, delimiter = '\t'):
        name = row['Name']
        percent = int(row['Percent Match'])
        if int(maxrows.get(name,row)['Percent Match']) <= percent:
            maxrows[name] = row

print(maxrows)
您可以使用csv解析选项卡描述的数据文件,尽管您发布的数据看起来是以列为间隔的数据

由于数据文件中的第一行给出了字段名,因此DictReader非常方便,因此您可以通过人类可读的名称来引用列

csv.DictReader返回一个dicts行的iterable。如果使用“匹配百分比”列作为键获取iterable的最大值,则可以找到匹配百分比最高的行:

将此选项卡分隔的数据用作test.dat:

节目

import csv

maxrows = {}
with open('test.dat', 'rb') as f:
    for row in csv.DictReader(f, delimiter = '\t'):
        name = row['Name']
        percent = int(row['Percent Match'])
        if int(maxrows.get(name,row)['Percent Match']) <= percent:
            maxrows[name] = row

print(maxrows)

我认为您可能正在寻找以下内容:

from collections import defaultdict

results = defaultdict(list)
with open('data.txt') as f:
    #next(f)      # you may need this so skip the header
    for line in f:
        splitted = line.split()
        results[splitted[0]].append(splitted[1:])

maxs = {}
for uid,data in results.items():
    maxs[uid] =  max(data, key=lambda k: int(k[1]))
我对一个文件进行了测试,如:

Name    Organism    Percent Match     Misc info
1        Human        100              xxx     
1        Goat          95              yyy
1        Pig           90              zzz   
2        Pig           85              zzz   
2        Goat          70              yyy
结果是:

{'1': ['Human', '100', 'xxx'], '2': ['Pig', '85', 'zzz']}

我认为您可能正在寻找以下内容:

from collections import defaultdict

results = defaultdict(list)
with open('data.txt') as f:
    #next(f)      # you may need this so skip the header
    for line in f:
        splitted = line.split()
        results[splitted[0]].append(splitted[1:])

maxs = {}
for uid,data in results.items():
    maxs[uid] =  max(data, key=lambda k: int(k[1]))
我对一个文件进行了测试,如:

Name    Organism    Percent Match     Misc info
1        Human        100              xxx     
1        Goat          95              yyy
1        Pig           90              zzz   
2        Pig           85              zzz   
2        Goat          70              yyy
结果是:

{'1': ['Human', '100', 'xxx'], '2': ['Pig', '85', 'zzz']}

注意:在上面的示例文件中,每个1是该项的名称,100、95和90是匹配的百分比等>。<不要将列表用作变量名,或dict。是否在循环中执行给定的代码?在这种情况下,它将在读取整个文件之前打印密钥。此外,在对列表进行排序后,my_list[0]将是最小的项,而不是最大的项。注意:上面的示例文件中,每个1是该项的名称,100、95和90是匹配的百分比等等。<不要将list用作变量名,也不要使用dict。是否在循环中执行给定的代码?在这种情况下,它将在读取整个文件之前打印密钥。此外,在对列表排序后,my_list[0]将是最小的项,而不是最大的项。非常有趣,谢谢!然而,我认为主要是由于我的输入文件示例中的一个错误,如果有多个输入,这个脚本只打印max行,而不打印max行。这是我没有具体说明的错误。谢谢你给我看导入csv!好的,我把它改了一点,每个名字最多收集一行。非常有趣,谢谢!然而,我认为主要是由于我的输入文件示例中的一个错误,如果有多个输入,这个脚本只打印max行,而不打印max行。这是我没有具体说明的错误。谢谢你给我看导入csv!好的,我把它改了一点,每个名字最多只能收集一行。@Vince:不客气!别忘了给社区一些回报——投票选出好的答案和最有用的答案:@Vince:不客气!别忘了给社区一些回报——投票选出好的答案和最有用的答案: