简体   繁体   English

在具有列表值的字典中按索引计算最大元素的 Pythonic 方法

[英]Pythonic way of counting max elements by index in a dictionary with list values

I want to compare the lists inside a dictionary (as values) by each index, and save in another dictionary how many times each "key" had the highest value.我想按每个索引比较字典中的列表(作为值),并在另一个字典中保存每个“键”具有最高值的次数。

Let's put an example, I have this dictionary:举个例子,我有这本字典:

my_dict = {'a': [1, 2, 5], 'b': [2, 1, 4], 'c': [1, 0, 3]}

I want to end up with a dictionary like this:我想以这样的字典结尾:

count_dict = {'a': 2, 'b': 1, 'c': 0}

Because:因为:

  • at index 0 of the lists we have: 1 from 'a';在列表的索引 0 处,我们有: 1来自 'a'; 2 from 'b'; 2来自“b”; and 1 from 'c'.1来自“c”。

    So 'b' has the highest value for this index and adds one to the count.因此,'b' 具有该索引的最高值并在计数中加一。

  • at index 1 of the lists we have: 2 from 'a';在列表的索引 1 处,我们有: 2来自 'a'; 1 from 'b'; 1来自“b”; and 0 from 'c'.0来自 'c'。

    So 'a' has the highest value for this index and adds one to the count.因此,'a' 具有该索引的最高值并在计数中加一。

  • at index 2 of the lists we have: 5 from 'a';在列表的索引 2 处,我们有: 5来自 'a'; 4 from 'b'; 4来自“b”; and 3 from 'c'.3来自“c”。

    So 'a' has the highest value for this index and adds one to the count.因此,'a' 具有该索引的最高值并在计数中加一。


I've tried with Counter and max(my_dict, key=my_dict.get) .我试过Countermax(my_dict, key=my_dict.get) But what would be the most pythonic way instead of doing this:但是什么是最 pythonic 的方式而不是这样做:

for i in range(len(my_dict['a'])):
    max_value = max(my_dict[key][i] for key in my_dict)
    for key in my_dict:
        if my_dict[key][i] == max_value:
            max_count[key] += 1

print(max_count)

You can zip them:你可以 zip 他们:

res = {k:0 for k in my_dict}
keys = [*my_dict] # note that order in dictionaries is only guaranteed in python 3.7+
for l in zip(*my_dict.values()):
   res[keys[l.index(max(l))]] += 1

You can zip the values after manipulating them to contain their respective key:你可以zip操纵它们以包含它们各自的键后的values

zip(*([(k, v) for v in l] for k, l in my_dict.items()))
# gives: [(('a', 1), ('b', 2), ('c', 1)), (('a', 2), ('b', 1), ('c', 0)), (('a', 5), ('b', 4), ('c', 3))]

and now for each item, find the max according to the value , and increment the count of the matching key :现在对于每个项目,根据value找到max ,并增加匹配的计数:

from collections import Counter

my_dict = {'a': [1, 2, 5], 'b': [2, 1, 4], 'c': [1, 0, 3]}

c = Counter()
for item in zip(*([(k, v) for v in l] for k, l in my_dict.items())):
    c[max(item, key=lambda x: x[1])[0]] += 1

print(c)

Will print {'a': 2, 'b': 1} since c was never added.将打印{'a': 2, 'b': 1}因为从未添加c But the beauty with Counter s is that even if you do c['c'] you will still get 0 .但是Counter s 的美妙之处在于,即使你执行c['c']你仍然会得到0


This doesn't rely on the keys' order or index and so will work for any Python version.这不依赖于键的顺序或索引,因此适用于任何 Python 版本。

An alternative approach using zip() together with enumerate and lambda.zip()与枚举和 lambda 一起使用的替代方法。

dict_result = {key: 0 for key in my_dict}

for idx, values in enumerate(zip(*my_dict.values())):
    max_key = max(my_dict, key=lambda k: my_dict[k][idx])
    dict_result[max_key] += 1
    
print(dict_result)

{'a': 2, 'b': 1, 'c': 0}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM