在Python中按最大值子集化元组列表

时间:2016-03-02 19:53:19

标签: list python-2.7 dictionary tuples

我的问题来自discussion。我道歉,但由于我的水平,我无法在另一个答案下添加评论来提问我的问题。我有这个元组列表:

my_list = [('Scaffold100019', 98310), ('Scaffold100019', 14807), ('Scaffold100425', 197577), ('Scaffold100636', 326), ('Scaffold10064', 85415), ('Scaffold10064', 94518)]

我想创建一个字典,只存储定义为元组第一个元素的每个键的最大值:

my_dict = {'Scaffold100019': 98310, 'Scaffold100425': 197577, 'Scaffold100636': 326, 'Scaffold10064': 94518}

从MarcusMüller的答案开始,我有:

d = {}

#build a dictionary of lists
for x,y in my_list: d.setdefault(x,[]).append(y)

my_dict = {}

#build a dictionary with the max value only
for item in d: my_dict[item] = max(d[item])

通过这种方式,我实现了目标但是,是否有更简洁的方法来完成这项任务?

3 个答案:

答案 0 :(得分:3)

我建议这个解决方案只有一个循环,非常易读:

my_dict = {}

for x,y in my_list:
    if x in my_dict.keys():
        my_dict [x] = max (y, my_dict [x])
    else:
        my_dict [x] = y

答案 1 :(得分:2)

您可以使用collections.defaultdict

from collections import defaultdict

d = defaultdict(int)
for key, value in my_list:
    d[key] = max(d[key], value)

上面的代码适用于您的示例数据,但只有在每个键的最大值为非负值时才会起作用。这是因为defaultdict(int)在没有设置值时返回零,所以如果给定键的所有值都是负数,则得到的最大值将错误地为零。

如果给定密钥可以纯粹为负值,则可以进行以下更改:

d = defaultdict(lambda: -float('inf'))

通过此更改,当未设置键时将返回负无穷大,因此负值不再是一个问题。

答案 2 :(得分:0)

使用一切都大于None的事实和带有get的字典None方法作为后备返回值。

>>> d = {}
>>> for name, value in my_list:
...     if value > d.get(name, None):
...         d[name] = value
... 
>>> d
{'Scaffold100425': 197577, 'Scaffold10064': 94518, 'Scaffold100019': 98310, 'Scaffold100636': 326}

这将适用于每个循环的所有值和散列最多两次。