Trying to add to dictionary values by counting occ

2019-01-29 10:52发布

问题:

I'm trying to get a count of items in a list of lists and add those counts to a dictionary in Python. I have successfully made the list (it's a list of all possible combos of occurrences for individual ad viewing records) and a dictionary with keys equal to all the values that could possibly appear, and now I need to count how many times each occur and change the values in the dictionary to the count of their corresponding keys in the list of lists. Here's what I have:

import itertools
stuff=(1,2,3,4)
n=1
combs=list()
while n<=len(stuff):
    combs.append(list(itertools.combinations(stuff,n)))
    n = n+1
viewers=((1,3,4),(1,2,4),(1,4),(1,2),(1,4)) 
recs=list()
h=1
while h<=len(viewers):
    j=1
    while j<=len(viewers[h-1]):
       recs.append(list(itertools.combinations(viewers[h-1],j))) 
       j=j+1
    h=h+1
showcount={}
for list in combs:
    for item in list:
        showcount[item]=0    
for k, v in showcount:
        for item in recs:
            for item in item:
                if item == k:
                    v = v+1

I've tried a bunch of different ways to do this, and I usually either get 'too many values to unpack' errors or it simply doesn't populate. There are several similar questions posted but I'm pretty new to Python and none of them really addressed what I needed close enough for me to figure it out. Many thanks.

回答1:

Use a Counter instead of an ordinary dict to count things:

from collections import Counter

showcount = Counter()
for item in recs:
    showcount.update(item)

or even:

from collections import Counter
from itertools import chain

showcount = Counter(chain.from_iterable(recs))

As you can see that makes your code vastly simpler.



回答2:

If all you want to do is flatten your list of lists you can use itertools.chain()

>>> import itertools
>>> listOfLists = ((1,3,4),(1,2,4),(1,4),(1,2),(1,4)) 
>>> flatList = itertools.chain.from_iterable(listOfLists)

The Counter object from the collections module will probably do the rest of what you want.

>>> from collections import Counter
>>> Counter(flatList)
Counter({1: 5, 4: 4, 2: 2, 3: 1})


回答3:

I have some old code that resembles the issue, it might prove useful to people facing a similar problem.

import sys
file = open(sys.argv[-1], "r").read()
wordictionary={}
for word in file.split():
    if word not in wordictionary:
        wordictionary[word] = 1
    else:
        wordictionary[word] += 1
sortable = [(wordictionary[key], key) for key in wordictionary]
sortable.sort()
sortable.reverse()
for member in sortable: print (member)


回答4:

First, 'flatten' the list using a generator expression: (item for sublist in combs for item in sublist).

Then, iterate over the flattened list. For each item, you either add an entry to the dict (if it doesn't already exist), or add one to the value.

d = {}
for key in (item for sublist in combs for item in sublist):
    try:
        d[key] += 1
    except KeyError:  # I'm not certain that KeyError is the right one, you might get TypeError. You should check this
        d[key] = 1

This technique assumes all the elements of the sublists are hashable and can be used as keys.