对一个值使用数组上的计数器,同时保留其他值的索引

Using counter on array for one value while keeping index of other values

看完这个问题的答案How to count the frequency of the elements in a list?我想知道如何计算某事物的频率,同时通过索引之类的东西来检索一些额外的信息。例如

a = ['fruit','Item#001']
b = ['fruit','Item#002']
c = ['meat','Item#003']
foods = [a,b,c]

现在我想数一数水果在食物列表中的次数。如果我在每个数组 a、b 和 c 的第一个索引上使用计数器,结果将有水果的数量,但我无法访问它是哪个项目。本质上,如果我使用 most_common,我将得到一个水果出现次数的列表,如 ('fruit',2),我如何从这两次出现中获取所有项目。

我想避免使用类似这个问题的属性

例如,它将按照我的意愿执行,不一定是 Counter 方法实际执行的操作。

counts = Counter(foods)
counts.most_common(10)
print counts
-> (('fruit',2)('meat',1))
print counts[0].Something_Like_Expand_Method()
-> ['fruit','Item#001'],['fruit','Item#002']

要计算一个值出现的频率,同时您想 select 这些值,您只需 select 这些值并计算您 select 的次数:

fruits = [f for f in foods if f[0] == 'fruit']
fruit_count = len(fruits)

如果您需要对所有条目执行此操作,您确实需要使用字典分组您的条目:

food_groups = {}
for food in foods:
    food_groups.setdefault(food[0], []).append(food[1])

此时您可以询问任何组,加上它们的长度:

fruit = food_groups['fruit']
fruit_count = len(fruit)

如果您还需要知道哪种食物最常见,您可以使用 max() 函数:

most_common_food = max(food_groups, key=lambda f: len(food_groups[f]))  # just the food group name
most_common_food_items = max(food_groups.values(), key=len)  # just the food group name

或者您可以通过传入字典映射键到值长度从组中创建 Counter

group_counts = Counter({f: len(items) for f, items in food_groups.iteritems()})
for food, count in group_counts.most_common(2):
    print '{} ({}):'.format(food, count)
    print '  items {}\n'.format(', '.join(food_groups[food]))

演示:

>>> from collections import Counter
>>> a = ['fruit','Item#001']
>>> b = ['fruit','Item#002']
>>> c = ['meat','Item#003']
>>> foods = [a,b,c]
>>> food_groups = {}
>>> for food in foods:
...     food_groups.setdefault(food[0], []).append(food[1])
... 
>>> food_groups
{'fruit': ['Item#001', 'Item#002'], 'meat': ['Item#003']}
>>> group_counts = Counter({f: len(items) for f, items in food_groups.iteritems()})
>>> for food, count in group_counts.most_common(2):
...     print '{} ({}):'.format(food, count)
...     print '  items {}\n'.format(', '.join(food_groups[food]))
... 
fruit (2):
  items Item#001, Item#002

meat (1):
  items Item#003