简体   繁体   中英

Most pythonic way to initialize a dict

Suppose I have a dict like this

d = {
    1: [1,4,7],
    2: [2,5,8],
    0: [3,6,9]       
}

It can be constructed by

d = {}

for i in range(1,10):
    key = i % 3
    if key not in d: d[key] = []
    d[key].append(i)

I used this line if key not in d: d[key] = [] to check existence of the key/value pair in the dict and initiate the pair.

Is there a more pythonic way to achieve this?

This is probably best handled with a defaultdict , which will automatically create any key-value mapping that is accessed if it doesn't already exist. You pass a callable to the defaultdict constructor that will be used to initialize the value. For example:

>>> from collections import defaultdict
>>> d = defaultdict(list)
>>> d
defaultdict(list, {})
>>> d[3]
[]
>>> d
defaultdict(list, {3: []})

Using a comprehension:

>>> {n%3: list(range(n, n+7, 3)) for n in range(1,4)}
{0: [3, 6, 9], 1: [1, 4, 7], 2: [2, 5, 8]}

Using dict.setdefault() :

>>> d = {}
>>> for i in range(1, 10):
...     d.setdefault(i%3, []).append(i)
... 
>>> d
{0: [3, 6, 9], 1: [1, 4, 7], 2: [2, 5, 8]}

Using defaultdict :

>>> from collections import defaultdict
>>> d = defaultdict(list)
>>> for i in range(1, 10):
...     d[i%3].append(i)
... 
>>> d
defaultdict(<class 'list'>, {0: [3, 6, 9], 1: [1, 4, 7], 2: [2, 5, 8]})

You can use list slices [start:stop:step] nominclature

d={}
for i in range(3):
     d[i] = list(range(1,10))[(i+2)%3::3]

{0: [3, 6, 9],
 1: [1, 4, 7], 
 2: [2, 5, 8]}
from collections import defaultdict

d = defaultdict(list)
for i in range(1,10):
    key = i % 3
    d[key].append(i)
print(d)

out:

defaultdict(<class 'list'>, {0: [3, 6, 9], 1: [1, 4, 7], 2: [2, 5, 8]})

When each key is encountered for the first time, it is not already in the mapping; so an entry is automatically created using the default_factory function which returns an empty list. The list.append() operation then attaches the value to the new list. When keys are encountered again, the look-up proceeds normally (returning the list for that key) and the list.append() operation adds another value to the list. This technique is simpler and faster than an equivalent technique using dict.setdefault():

>>> d = {}
>>> for k, v in s:  
        d.setdefault(k, []).append(v)

Given that you haven't given any input nor variable parts you might just initialize it with the literal you already have:

d = {1: [1,4,7],
     2: [2,5,8],
     0: [3,6,9]}

If you have variable input you may use collections.defaultdict with list as factory. Given that this operation is very common several external libraries have functions for this:

For example:

>>> from iteration_utilities import groupedby

>>> groupedby(range(1, 10), lambda x: x % 3)
{0: [3, 6, 9], 1: [1, 4, 7], 2: [2, 5, 8]}

or:

>>> from toolz import groupby

>>> groupby(lambda x: x % 3, range(1, 10))
{0: [3, 6, 9], 1: [1, 4, 7], 2: [2, 5, 8]}

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