How to add or increment a dictionary entry?

PythonSyntax

Python Problem Overview


I'm currently re-engaging with Python after a long absence and loving it. However, I find myself coming across a pattern over and over. I keep thinking that there must be a better way to express what I want and that I'm probably doing it the wrong way.

The code that I'm writing is in the following form:

# foo is a dictionary
if foo.has_key(bar):
  foo[bar] += 1
else:
  foo[bar] = 1

I'm writing this a lot in my programs. My first reaction is to push it out to a helper function, but so often the python libraries supply things like this already.

Is there some simple little syntax trick that I'm missing? Or is this the way that it should be done?

Python Solutions


Solution 1 - Python

The dict's get() method takes an optional second parameter that can be used to provide a default value if the requested key is not found:

foo[bar] = foo.get(bar, 0) + 1

Solution 2 - Python

Use a defaultdict:

from collections import defaultdict

foo = defaultdict(int)
foo[bar] += 1

In Python >= 2.7, you also have a separate Counter class for these purposes. For Python 2.5 and 2.6, you can use its backported version.

Solution 3 - Python

I did some time comparisons. Pretty much equal. The one-lined .get() command is fastest, though.

Output:

get 0.543551800627
exception 0.587318710994
haskey 0.598421703081

Code:

import timeit
import random

RANDLIST = [random.randint(0, 1000) for i in range(10000)]

def get():
    foo = {}
    for bar in RANDLIST:
        foo[bar] = foo.get(bar, 0) + 1


def exception():
    foo = {}
    for bar in RANDLIST:
        try:
            foo[bar] += 1
        except KeyError:
            foo[bar] = 1


def haskey():
    foo = {}
    for bar in RANDLIST:
        if foo.has_key(bar):
            foo[bar] += 1
        else:
            foo[bar] = 1


def main():
    print 'get', timeit.timeit('get()', 'from __main__ import get', number=100)
    print 'exception', timeit.timeit('exception()', 'from __main__ import exception', number=100)
    print 'haskey', timeit.timeit('haskey()', 'from __main__ import haskey', number=100)


if __name__ == '__main__':
    main()

Solution 4 - Python

You can also take advantage of the control structure in exception handling. A KeyError exception is thrown by a dictionary when you try to assign a value to a non-existent key:

my_dict = {}
try:
    my_dict['a'] += 1
except KeyError, err:    # in 2.6: `except KeyError as err:`
    my_dict['a'] = 1

Solution 5 - Python

For Python >= 2.5 you can do the following:

foo[bar] = 1 if bar not in foo else foo[bar]+1

Solution 6 - Python

I don't know how this was tried, but if you need to append items in dict keys...

indicatorDict = {}
indicatorDict[0] = 'Langford'
indicatorDict[1] = 'Esther'
indicatorDict[3] = 14

Append items to it, be it iteratively or other types:

indicatorDict[0] = np.append(indicatorDict[0],'Auditorium')
indicatorDict[1] = np.append(indicatorDict[1],'Duflo')
indicatorDict[3] = np.append(indicatorDict[3],'November') 

Printing ...

{0: array(['Langford', 'Auditorium'], dtype='<U10'),
 1: array(['Esther', 'Duflo'], dtype='<U6'),
 3: array(['14', 'November'], dtype='<U11')}

I avoided 3rd key in Dict to show that if needed keys can be jumped from one step to another... :) Hope it helps!

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestioncursaView Question on Stackoverflow
Solution 1 - PythonsthView Answer on Stackoverflow
Solution 2 - PythonTamásView Answer on Stackoverflow
Solution 3 - Pythonuser297250View Answer on Stackoverflow
Solution 4 - PythonSantaView Answer on Stackoverflow
Solution 5 - PythonthetaikoView Answer on Stackoverflow
Solution 6 - PythonbanikrView Answer on Stackoverflow