简体   繁体   中英

count of sublists containing item for all items

I'm looking for a more efficient/pythonic way of doing this.

l = [[0,0],[1,0],[4,5,1],[2,3,5],[0,4]]

set_l = set([i for sl in l for i in sl])

sublists_containing_item_count = [sum([1 for x in l if i in x]) for i in set_l]

count_dict = dict(zip(set_l,sublists_containing_item_count))

count_dict

{0: 3, 1: 2, 2: 1, 3: 1, 4: 2, 5: 2}

You can use collections.Counter to produce a dict of counts and use itertools.chain.from_iterable to flatten your nested list

>>> from collections import Counter
>>> import itertools

>>> l = [[0],[1,0],[4,5,1],[2,3,5],[0,4]]
>>> c = Counter(itertools.chain.from_iterable(l))
>>> c
Counter({0: 3, 1: 2, 4: 2, 5: 2, 2: 1, 3: 1})

You want to get efficient/Pythonic ways.

collections.Counter

from collections import Counter

l = [[0],[1,0],[4,5,1],[2,3,5],[0,4]]

count_dict = Counter([i for sl in l for i in sl])

So very Pythonic.

collections.defaultdict

from collections import defaultdict

l = [[0],[1,0],[4,5,1],[2,3,5],[0,4]]
count_dict = defaultdict(int)

for sl in l:
    for i in sl:
        count_dict[i] += 1

So very simple dict.

Short code with sum() and collections.Counter()

from collections import Counter
l = [[0],[1,0],[4,5,1],[2,3,5],[0,4]]
count_dict = Counter(sum(l,[]))

result

print(count_dict)

If you can afford to use packages outside the standard library, then more_itertools could provide a more readable solution:

from more_itertools import flatten
from collections import Counter

l = [[0],[1,0],[4,5,1],[2,3,5],[0,4]]
c = Counter(flatten(l))
print(c)

You can use the Counter update method to add/update the count as you add more iterables to it.

Elements are counted from an iterable or added-in from another mapping (or counter). Like dict.update() but adds counts instead of replacing them. Also, the iterable is expected to be a sequence of elements, not a sequence of (key, value) pairs.

from collections import Counter

l = [[0], [1, 0], [4, 5, 1], [2, 3, 5], [0, 4]]
count = Counter()  # initialize an empty counter

for lst in l:
    count.update(lst)
print(dict(count))

Output:

{0: 3, 1: 2, 4: 2, 5: 2, 2: 1, 3: 1}

I can't say that this is more "efficient", but I think it's safe to say that it's more Pythonic. Use a dictionary comprehension:

>>> l = [[0],[1,0],[4,5,1],[2,3,5],[0,4]]
>>> {i:sum([sl.count(i) for sl in l]) for i in set([i for sl in l for i in sl])}
{0: 3, 1: 2, 2: 1, 3: 1, 4: 2, 5: 2}

As I can see from the explanation, you are trying to count the occurrence of each number.

Here is a way you can do it using python's inbuild func.

from collections import Counter

l = [[0],[1,0],[4,5,1],[2,3,5],[0,4]]

arr = [i for sl in l for i in sl]

count_dict = Counter(arr)

print(count_dict)

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