30

I have a dictionary of lists, and it should be initialized with default keys. I guess, the code below is not good (I mean, it works, but I don't feel that it is written in the pythonic way):

d = {'a' : [], 'b' : [], 'c' : []}

So I want to use something more pythonic like defaultict:

d = defaultdict(list)

However, every tutorial that I've seen dynamically sets the new keys. But in my case all the keys should be defined from the start. I'm parsing other data structures, and I add values to my dictionary only if specific key in the structure also contains in my dictionary.

How can I set the default keys?

Amir
  • 1,926
  • 3
  • 23
  • 40
  • Do you want additional keys created automatically later or do you have the full set from the beginning? – tdelaney Mar 21 '17 at 05:03
  • 3
    If you're using a defaultdict, why do you need to set the keys? What's the behaviour you want, what's the use case for this data structure? – jonrsharpe Mar 21 '17 at 05:09
  • @tdelaney I want the full set from the beginning. – Amir Mar 21 '17 at 05:17
  • @jonrsharpe I'm parsing other data structures, and I add values to my dictionary only if specific key in the structure also contains in my dictionary. – Amir Mar 21 '17 at 05:20
  • Please [edit] the question to provide context and illustrate why your current solution is falling short. – jonrsharpe Mar 21 '17 at 05:20
  • `I mean, it works, but I don't feel that it is written in the pythonic way` - I don't see any issues with how "pythonic" your existing code is in this case. And wouldn't recommend chasing down every possible instance of 'unpythonic' code in general – Marius Mar 21 '17 at 05:26

6 Answers6

33

From the comments, I'm assuming you want a dictionary that fits the following conditions:

  1. Is initialized with set of keys with an empty list value for each
  2. Has defaultdict behavior that can initialize an empty list for non-existing keys

@Aaron_lab has the right method, but there's a slightly cleaner way:

d = defaultdict(list,{ k:[] for k in ('a','b','c') })
rovyko
  • 4,068
  • 5
  • 32
  • 44
16

That's already reasonable but you can shorten that up a bit with a dict comprehension that uses a standard list of keys.

>>> standard_keys = ['a', 'b', 'c']
>>> d1 = {key:[] for key in standard_keys}
>>> d2 = {key:[] for key in standard_keys}
>>> ...
tdelaney
  • 73,364
  • 6
  • 83
  • 116
10

If you're going to pre-initialize to empty lists, there is no need for a defaultdict. Simple dict-comprehension gets the job done clearly and cleanly:

>>> {k : [] for k in ['a', 'b', 'c']}
{'a': [], 'b': [], 'c': []}
Raymond Hettinger
  • 216,523
  • 63
  • 388
  • 485
8

If you have a close set of keys (['a', 'b', 'c'] in your example) you know you'll use, you can definitely use the answers above.

BUT...

dd = defaultdict(list) gives you much more then: d = {'a':[], 'b':[], 'c':[]}. You can append to "not existing" keys in defaultdict:

>>dd['d'].append(5)
>>dd
>>defaultdict(list, {'d': 5})

where if you do:

>>d['d'].append(5)  # you'll face KeyError
>>KeyError: 'd'

Recommend to do something like:

>>d = {'a' : [], 'b' : [], 'c' : []}
>>default_d = defaultdict(list, **d)

now you have a dict holding your 3 keys: ['a', 'b', 'c'] and empty lists as values, and you can also append to other keys without explicitly writing: d['new_key'] = [] before appending

Aaron_ab
  • 3,450
  • 3
  • 28
  • 42
1

You can have a function defined which will return you a dict with preset keys.

def get_preset_dict(keys=['a','b','c'],values=None):
    d = {}
    if not values:
        values = [[]]*len(keys)
    if len(keys)!=len(values):
        raise Exception('unequal lenghts')
    for index,key in enumerate(keys):
        d[key] = values[index]

    return d

In [8]: get_preset_dict()

Out[8]: {'a': [], 'b': [], 'c': []}

In [18]: get_preset_dict(keys=['a','e','i','o','u'])

Out[18]: {'a': [], 'e': [], 'i': [], 'o': [], 'u': []}

In [19]: get_preset_dict(keys=['a','e','i','o','u'],values=[[1],[2,2,2],[3],[4,2],[5]])

Out[19]: {'a': [1], 'e': [2, 2, 2], 'i': [3], 'o': [4, 2], 'u': [5]}

harshil9968
  • 3,254
  • 1
  • 16
  • 26
0
from collections import defaultdict
list(map((data := defaultdict(list)).__getitem__, 'abcde'))
data

Out[3]: defaultdict(list, {'a': [], 'b': [], 'c': [], 'd': [], 'e': []})

mcstarioni
  • 312
  • 1
  • 13