Given a list of lists, how can I create a dictionary where the keys are all the items in the list (one copy), and the values are the number of times they are the first item in the list?
Given:
[['banana', 'oranges', 'grapes'],['banana', 'grapes'],['grapes', 'oranges', 'banana']]
Expected:
{'banana': 2, 'grapes': 1, 'oranges': 0}
First get the list of first elements:
filtered_list = [x[0] for x in initial_list]
And here are your unique elements:
unique_elements = set([y for x in initial_list for y in x])
Now initialize a dictionary with keys from unique elements and values of zero:
counts = {e: 0 for e in unique_elements}
Finally update the values of the dictionary with the frequencies of each element in the filtered list. Since you asked a solution without counter
, here is a simple loop to achieve that:
for i in filtered_list:
counts[i] = counts.get(i, 0) + 1
print(counts)
# {'banana': 2, 'grapes': 1, 'oranges': 0}
You can use sets to get unique names present in the sub lists:
initial_list = [['banana', 'oranges', 'grapes'],['banana', 'grapes'],['grapes', 'oranges', 'banana']]
unique = set()
for l in initial_list:
unique = unique.union(set(l))
Then counting in how many list each item is present (assuming each item is either present or not, not duplicated):
from collections import defaultdict
result = defaultdict(lambda: 0)
for element in unique:
for l in initial_list:
result[element] += (element == l[0])
Defaultict is used to get an initial value of 0 And you should have your result in result
The fact that bool
are a subclass of int
is used to evaluate element == l[0]
either to 1
or 0
Without collections
you would need to edit the last line to be:
try:
result[element] += (element == l[0])
except KeyError:
result[element] = 1
Create list of lists:
ll = [['banana', 'oranges', 'grapes'], ['banana', 'grapes'], ['grapes', 'oranges', 'banana']]
Get unique keys:
from itertools import chain
d = dict.fromkeys(chain(*ll), 0)
Count first elements of lists:
from collections import Counter
from operator import itemgetter
c = Counter(map(itemgetter(0), ll))
Update and show result:
d.update(dict(c))
print(d)
Prints:
{'banana': 2, 'oranges': 0, 'grapes': 1}
All the previous responses failed for me. This is a very fast implementation that works:
# l is a list of lists
import itertools
ext_l = list(itertools.chain.from_iterable(l))
l_dic = {element:0 for element in set(ext_l)}
for i in ext_l: l_dic[i] += 1
print(l)
Simple implementation
l = [['banana', 'oranges', 'grapes'],['banana', 'grapes'],['grapes', 'oranges', 'banana']]
unique_items = set([i for sl in l for i in sl])
d = dict()
for item in unique_items:
d[item] = 0
for sublist in l:
d[sublist[0]] += 1
print(d)
# output
# {'grapes': 1, 'oranges': 0, 'banana': 2}
To maintain order
d = dict()
for sl in l:
d[sl[0]] = d.get(sl[0],0) + 1
print(d)
# {'banana': 2, 'grapes': 1}
unique_items = set([i for sl in l for i in sl])
for item in unique_items:
if item not in d:
d[item] = 0
print(d)
# {'banana': 2, 'grapes': 1, 'oranges': 0}
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.