2

A snippet of code from a working script; I'm just curious if there's a "prettier" way to achieve the same result.

    if ctry in countries:
        countries[ ctry ] += 1
    else:
        countries[ ctry ] = 1

In awk I could have just used countries[ ctry ] += 1, but python threw a key error (understandably).

Marcin Zablocki
  • 8,896
  • 1
  • 39
  • 46
tink
  • 12,902
  • 4
  • 44
  • 47
  • [Check if a given key already exists in a dictionary and increment it](https://stackoverflow.com/q/473099/2301450) – vaultah Aug 19 '17 at 21:56
  • You might want [collections.Counter](https://docs.python.org/3/library/collections.html#collections.Counter) for that. – Izaak van Dongen Aug 19 '17 at 22:33

3 Answers3

6

Rather than using a normal dictionary, you could change countries to be a collections.defaultdict object instead. As the name implies, collections.defaultdict allows you to have a default value inserted in your dictionary if a key doesn't exist yet:

from collections import defaultdict
countries = defaultdict(int)

Then your snippit becomes one line:

countries[cntry] += 1

If you can't use collections.defaultdict, you can use the "ask forgiveness rather than permission" idiom instead:

try:
    countries[ ctry ] += 1
except KeyError:
    countries[ ctry ] = 1

Although the above will behave like your conditional statement, it is consider more "Pythonic" because try/except is used rather than if/else.

Christian Dean
  • 20,986
  • 7
  • 47
  • 78
3

The following is a bit more pythonic:

countries[ctry]  = 1 if ctry not in countries else countries[ctry] + 1

Or

countries[ctry] = countries.get(ctry, 0) + 1
Dekel
  • 57,326
  • 8
  • 92
  • 123
2

Another option is to use defaultdict:

from collections import defaultdict
countries = defaultdict(int)
countries[ctry] += 1

Speed test:

%timeit countries['Westeros'] += 1
10000000 loops, best of 3: 79 ns per loop

countries = {}
%timeit countries['Westeros'] = countries.get('Westeros', 0) + 1
1000000 loops, best of 3: 164 ns per loop
Yigal
  • 1,315
  • 12
  • 22