简体   繁体   中英

How do I count each unique value for each key in a dictionary containing lists?

I have the following dictionary:

dict = {'A': [1,1,2], 'B': [1,1,1], 'C': [2,2,2,1,2]}

I want the output to tell me how many of each values I have for each key, eg:

if value == 1  -> A, 2; B,3; C,1
if value == 2   -> A, 1; B,0; C,4

So far I have:

for i in dict[i]:
    if i == 1:
        participants_luck += 1
    elif i == 2:
        participants_skill += 1
    

This is a flexible solution to count the occurrences of each different value in the dictionary

dict = {"A": [1,1,2], "B": [1,1,1], "C": [2,2,2,1,2]}
different_values = set()

for values in dict.values():
    for el in values:
        different_values.add(el)

for possible_value in different_values:
    print(possible_value)
    for key, values in dict.items():
        print(key, sum(value == possible_value for value in values))
    print("\n")

Output:

1
A 2
B 3
C 1


2
A 1
B 0
C 4

UPDATE: If you want to handle also non list items in dict you can do like this:

from collections.abc import Iterable

dict = {"A": [1,1,2], "B": [1,1,1], "C": [2,2,2,1,2], "D": 1}
different_values = set()

for values in dict.values():
    if isinstance(values, Iterable):
        for el in values:
                different_values.add(el)
    else:
        different_values.add(values)


for possible_value in different_values:
    print(possible_value)
    for key, values in dict.items():
        if isinstance(values, Iterable):
            print(key, sum(value == possible_value for value in values))
        else:
            print(key, int(values == possible_value))
    print("\n")

And the output will be:

1
A 2
B 3
C 1
D 1


2
A 1
B 0
C 4
D 0

Define a function so you can search for different values if you ever need to. Use the count method to make things very easy for yourself.

d = {'A': [1,1,2], 'B': [1,1,1], 'C': [2,2,2,1,2]}

def foo(value, dictionary):
    for key,l in dictionary.items():
        print(f"{key} : {l.count(value)}")

foo(1,d)
foo(2,d)

Would be interesting making a function to do it.

def count_stuff(any_dict, wanted_val):
    counted_dict = {}
    for key in any_dict.keys():
        count = 0
        for element in any_dict[key]:
            count += (element == wanted_val)
        counted_dict[key] = count
    
    return counted_dict

Running your example...

your_dict = {"A": [1,1,2], "B": [1,1,1], "C": [2,2,2,1,2]}
for i in [1, 2]:
    print(i, count_stuff(your_dict, i))

Prints

1 {'A': 2, 'B': 3, 'C': 1}
2 {'A': 1, 'B': 0, 'C': 4}

This is a one-liner! You can write a dictionary comprehension. We have a dictionary mydict and a value to count. We first iterate over the items in the dictionary. For each list in the dictionary, we iterate over that list, and find the sum of i == value . Because True counts as 1 and False counts as 0, sum(i == value for i in lst) will give the number of i in the lst which are equal to value . Alternatively, you could do lst.count(value) . The sum(...) technique is useful when you want to count a condition other than == , for example if you wanted to count how many elements are less than the given value.

def count(mydict, value):
    return {k: sum(i == value for i in lst) for k, lst in mydict.items()}
    # Or, 
    # return {k: lst.count(value) for k, lst in mydict.items()}

d = {'A': [1,1,2], 'B': [1,1,1], 'C': [2,2,2,1,2]}
count(d, 1) # out: {'A': 2, 'B': 3, 'C': 1}
count(d, 2) # out: {'A': 1, 'B': 0, 'C': 4}

You can then access the counts like so:

result = count(d, 1)
print(f"A: {result['A']}, B: {result['B']}, C: {result['C']}")

Or, if you don't want to hardcode the keys of result :

result = count(d, 1)
for k, v in result.items():
    print(f"{k}: {v}")

You could use a Counter:

from collections import Counter
cnts={k: Counter(v) for k,v in di.items()}

# {'A': Counter({1: 2, 2: 1}), 'B': Counter({1: 3}), 'C': Counter({2: 4, 1: 1})}

Then just use a comprehension to get the sub counts as needed:

>>> {k:v[1] for k,v in cnts.items()}
{'A': 2, 'B': 3, 'C': 1}
>>> ({k:v[2] for k,v in cnts.items()}
{'A': 1, 'B': 0, 'C': 4}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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