Python 从(ID,number)对中,仅保留包含最大数字的对

Python 从(ID,number)对中,仅保留包含最大数字的对,python,regex,Python,Regex,我是python新手,我想就一个小问题获得一些帮助。我有一个文件,它的每一行都有一个ID和一个关联的数字。同一个ID可以关联多个数字。在python中,如何仅获取ID加上与其关联的最大数字 例如: 输入:ID_file.txt ENSG0000133246 2013ENSG0000133246 540 ENSG0000133246 2010 ENSG0000253626 465 ENSG0000211829464 ENSG00001584582577 ENSG0000158453 我想要的是:

我是python新手,我想就一个小问题获得一些帮助。我有一个文件,它的每一行都有一个ID和一个关联的数字。同一个ID可以关联多个数字。在python中,如何仅获取ID加上与其关联的最大数字

例如:

输入:ID_file.txt

ENSG0000133246 2013
ENSG0000133246 540
ENSG0000133246 2010
ENSG0000253626 465
ENSG0000211829464
ENSG00001584582577
ENSG0000158453

我想要的是:

ENSG0000133246 2013
ENSG0000253626 465
ENSG0000211829464
ENSG0000158457


提前感谢您的帮助

我想有很多方法可以做到这一点,尽管我会使用字典

from collections import defaultdict

id_value_dict = defaultdict()
for line in open(idfile.txt).readlines():
    id, value = line.strip().split()
    if id not in id_value_dict:
        id_value_dict[id] = int(value)
    else:
        if id_value_dict[id] < int(value):
            id_value_dict[id] = int(value)
有更巧妙的方法可以做到这一点,我认为这本字典可以用lamda或列表理解写成一行,但我喜欢从简单开始

如果您需要对结果进行排序,有很多方法可以做到这一点,但我认为理解在python中使用列表和字典是至关重要的,因为我发现学习思考正确的数据容器通常是解决我的许多问题的关键,但我仍然是一个新手。如果您需要排序结果,任何简单的方法都是

 id_value_dict.keys().sort() 
这是python id_value_udict的精巧之处之一。keys()是字典中的键列表

 out_ref = open(outputfile.txt,'w')
 for key in id_value_dict.keys():
     outref.write(key + '\t' + str(id_value_dict[key])

 outref.close()
这真的很棘手,因为您可能想要(我知道我一直想要)编写代码


但是,您会发现我的排序列表不存在(非类型)

我认为有很多方法可以做到这一点,尽管我会使用字典

from collections import defaultdict

id_value_dict = defaultdict()
for line in open(idfile.txt).readlines():
    id, value = line.strip().split()
    if id not in id_value_dict:
        id_value_dict[id] = int(value)
    else:
        if id_value_dict[id] < int(value):
            id_value_dict[id] = int(value)
有更巧妙的方法可以做到这一点,我认为这本字典可以用lamda或列表理解写成一行,但我喜欢从简单开始

如果您需要对结果进行排序,有很多方法可以做到这一点,但我认为理解在python中使用列表和字典是至关重要的,因为我发现学习思考正确的数据容器通常是解决我的许多问题的关键,但我仍然是一个新手。如果您需要排序结果,任何简单的方法都是

 id_value_dict.keys().sort() 
这是python id_value_udict的精巧之处之一。keys()是字典中的键列表

 out_ref = open(outputfile.txt,'w')
 for key in id_value_dict.keys():
     outref.write(key + '\t' + str(id_value_dict[key])

 outref.close()
这真的很棘手,因为您可能想要(我知道我一直想要)编写代码


但是,您会发现我的\u排序\u列表不存在(非类型)

鉴于您的输入只包含每个ID的连续运行,也就是说,一旦您看到另一个ID,您就再也看不到以前的ID了。您可以这样做:

import itertools
import operator

with open('ID_file.txt') as idfile, open('max_ID_file.txt', 'w') as maxidfile:
    keyvalpairs = (line.strip().split(None, 1) for line in idfile)
    for key, group in itertools.groupby(keyvalpairs, operator.itemgetter(0)):
        maxval = max(int(keyval[1]) for keyval in group)
        maxidfile.write('{} {}\n'.format(key, maxval))
要了解它的作用,让我们逐行检查它

一个文件只是一个满是行的iterable,因此idfile中的行的
的意思正是您所期望的。对于每一行,我们调用
strip
来去除多余的空白,然后
split(None,1)
在第一个空格处对其进行拆分,因此我们最终得到一个充满字符串对的iterable

下一步,我们使用将其更改为一个充满(键、组)对的iterable。尝试打印出
列表(keyvalpairs)
以查看其外观

然后我们迭代,只需使用
max
即可获得每组中的最大值


最后,我们打印出组的键和最大值。

鉴于您的输入只包括每个ID的连续运行,也就是说,一旦您看到另一个ID,您就再也看不到前一个ID,您可以这样做:

import itertools
import operator

with open('ID_file.txt') as idfile, open('max_ID_file.txt', 'w') as maxidfile:
    keyvalpairs = (line.strip().split(None, 1) for line in idfile)
    for key, group in itertools.groupby(keyvalpairs, operator.itemgetter(0)):
        maxval = max(int(keyval[1]) for keyval in group)
        maxidfile.write('{} {}\n'.format(key, maxval))
要了解它的作用,让我们逐行检查它

一个文件只是一个满是行的iterable,因此idfile中的行的
的意思正是您所期望的。对于每一行,我们调用
strip
来去除多余的空白,然后
split(None,1)
在第一个空格处对其进行拆分,因此我们最终得到一个充满字符串对的iterable

下一步,我们使用将其更改为一个充满(键、组)对的iterable。尝试打印出
列表(keyvalpairs)
以查看其外观

然后我们迭代,只需使用
max
即可获得每组中的最大值


最后,我们打印出组的键和最大值。

是否需要像示例输出那样保留顺序?此外,相同ID的运行是否始终与示例输入中的运行连续?还有,你为什么把“regex”标记放在这里?如果像abarnert所问的那样,相同ID的运行总是连续的,我会使用+max()@Bwmat:这正是我想说的。我想观察一下,如果你这样假设,那么如果你的输入不符合你期望的顺序,你会遇到更多的麻烦。你永远不会知道是否有问题。这些看起来像是来自传感器或遗传数据的轮询值。如果它是遗传数据,那么它应该是有序的,但是如果它不是遗传数据,那么你需要期待一个更一般的表达式。@PyNEwbie:这就是为什么我问OP,并确保在我的回答中指出这个假设,而不是只是默默地假设它。顺序也很可能很重要,在这种情况下,您的
dict
解决方案将给出错误的答案,这就是为什么我也向OP询问这个问题。当你有一个不明确的问题时,最好指出所有的假设,并要求对其进行验证。你是否需要像你的样本输出那样保持秩序?此外,相同ID的运行是否始终与示例输入中的运行连续?还有,你为什么把“regex”标记放在这里?如果像abarnert所问的那样,相同ID的运行总是连续的,我会使用+max()@Bwmat:这正是我想说的。我想观察一下,如果你这样假设,那么如果你的输入不符合你期望的顺序,你会遇到更多的麻烦。你