scharfmn
scharfmn

Reputation: 3661

How to add or increment single item of the Python Counter class

A set uses .update to add multiple items, and .add to add a single one.

Why doesn't collections.Counter work the same way?

To increment a single Counter item using Counter.update, it seems like you have to add it to a list:

from collections import Counter

c = Counter()
for item in something:
    for property in properties_of_interest:
        if item.has_some_property: # simplified: more complex logic here
            c.update([item.property])
        elif item.has_some_other_property:
            c.update([item.other_property])
        # elif... etc

Can I get Counter to act like set (i.e. eliminate having to put the property in a list)?

Use case: Counter is very nice because of its defaultdict-like behavior of providing a default zero for missing keys when checking later:

>>> c = Counter()
>>> c['i']
0

I find myself doing this a lot as I'm working out the logic for various has_some_property checks (especially in a notebook). Because of the messiness of that, a list comprehension isn't always desirable etc.

Upvotes: 59

Views: 99362

Answers (3)

Vidhya G
Vidhya G

Reputation: 2320

>>> c = collections.Counter(a=23, b=-9)

You can add a new element and set its value like this:

>>> c['d'] = 8
>>> c
Counter({'a': 23, 'd': 8, 'b': -9})

Increment:

>>> c['d'] += 1
>>> c
Counter({'a': 23, 'd': 9, 'b': -9} 

Note though that c['b'] = 0 does not delete:

>>> c['b'] = 0
>>> c
Counter({'a': 23, 'd': 9, 'b': 0})

To delete use del:

>>> del c['b']
>>> c
Counter({'a': 23, 'd': 9})

Counter is a dict subclass

Upvotes: 28

shx2
shx2

Reputation: 64288

Well, you don't really need to use methods of Counter in order to count, do you? There's a += operator for that, which also works in conjunction with Counter.

c = Counter()
for item in something:
    if item.has_some_property:
        c[item.property] += 1
    elif item.has_some_other_property:
        c[item.other_property] += 1
    elif item.has_some.third_property:
        c[item.third_property] += 1

Upvotes: 53

Christian Aichinger
Christian Aichinger

Reputation: 7227

There is a more Pythonic way to do what you want:

c = Counter(item.property for item in something if item.has_some_property)

It uses a generator expression instead of open-coding the loop.

Edit: Missed your no-list-comprehensions paragraph. I still think this is the way to actually use Counter in practice. If you have too much code to put into a generator expression or list comprehension, it is often better to factor that into a function and call that from a comprehension.

Upvotes: 7

Related Questions