Make a dictionary of two lists using Counter object
I have the following list:
name = ["Anne", "Jack", "Mary"]
I also have a nested list where each item is a different list and is associated with the name present in the index name
. This is shown below:
n1 = [[0, 0, 3], [0, 5, 5], [1, 3, 3]]
So, for 'Anne'
, the first item in the list name
, the associated list of n1
is the first item [0, 0, 3]
.
Likewise, for the "Jack"
second item in the list name
, the associated list of n1
is the second item, [0, 5, 5]
and so on.
I want to count the number of each number in each element n1
and associate it with the names in a list name
in dictionary format.
So, I want my output to look like this:
{'Anne': {'0': 2, '3': 1}, 'Jack': {'0': 1, '5': 2}, 'Mary': {'1': 1, '3': 2}}
I've tried the following:
from collections import Counter
clust = {}
for val in name:
clust[val] = {}
for e in n1:
wc = Counter(str(e1) for e1 in e)
clust[val] = dict(wc)
But this gives me the result:
clust = {'Anne': {'1': 1, '3': 2}, 'Jack': {'1': 1, '3': 2}, 'Mary': {'1': 1, '3': 2}}
This is not true. How do I achieve the result I want?
source to share
You need to map data from n1
to each item in name
; the simplest way is zip
:
>>> from collections import Counter
>>> name = ["Anne", "Jack", "Mary"]
>>> n1 = [[0,0,3], [0,5,5], [1,3,3]]
>>> {name_: Counter(data) for name_, data in zip(name, n1)}
{'Anne': Counter({0: 2, 3: 1}), 'Jack': Counter({5: 2, 0: 1}), 'Mary': Counter({3: 2, 1: 1})}
(Note the use of "vocabulary comprehension", see docs .)
If keys in strings Counter
are critical, you can use map
to convert integers before counting:
>>> {name_: Counter(map(str, data)) for name_, data in zip(name, n1)}
{'Anne': Counter({'0': 2, '3': 1}), 'Jack': Counter({'5': 2, '0': 1}), 'Mary': Counter({'3': 2, '1': 1})}
source to share
For each name, the loop loops for e in n1:
over all n1 elements, creating a counter for each of them and setting clust[val]
to the result. Thus, it clust[val]
ends up as a result of only the last item in the n1
.
You should use zip()
to concatenate the name of the two lists and n1 into one, or probably better, a list of names and the resulting counters from n1. zip()
returns tuples with elements taken from both lists ( zip([1, 2], ['a', 'b']) becomes [(1, 'a'), (2, 'b')]
. You can make dict
from such tuples directly.
So:
clust = dict(zip(name, [Counter(e) for e in n1]))
source to share
Just use the index value of the list name
to count the items in the sublist n1
. This can be done using enumerate(name)
. It returns the value and its index. Use this returned index to count the items in the substring n1
that match the item in name
.
>>> from collections import Counter
>>> name = ["Anne", "Jack", "Mary"]
>>> n1 = [[0,0,3], [0,5,5], [1,3,3]]
>>> clust = {}
>>> for i,val in enumerate(name):
... wc = Counter(str(e1) for e1 in n1[i])
... clust[val] = dict(wc)
...
>>> clust
{'Anne': {'0': 2, '3': 1}, 'Jack': {'0': 1, '5': 2}, 'Mary': {'1': 1, '3': 2}}
source to share
You need to do it like this:
from collections import Counter
name = ["Anne", "Jack", "Mary"]
n1 = [[0,0,3], [0,5,5], [1,3,3]]
clust = {name[i]: Counter(n1[i]) for i in range(len(name))}
Output:
{'Anne': Counter({0: 2, 3: 1}),
'Jack': Counter({5: 2, 0: 1}),
'Mary': Counter({3: 2, 1: 1})}
source to share