I have a list of day names (typically Monday-Saturday, though special cases apply) that I want to create a dictionary out of. I want to initialize the value of each day to zero.
If I had a list of zeroes the same length of the list of days, this would be a simple use case of zip(). However, a list of zeroes is a waste of space, and if that were the only solution I'd just as soon do something like:
for day in weekList:
dayDict[day] = 0
Is there a more pythonic way?
A dictionary is 6.6 times faster than a list when we lookup in 100 items.
In Python, a Nested dictionary can be created by placing the comma-separated dictionaries enclosed within braces.
It is well-known that in Python tuples are faster than lists, and dicts are faster than objects.
The reason is because a dictionary is a lookup, while a list is an iteration. Dictionary uses a hash lookup, while your list requires walking through the list until it finds the result from beginning to the result each time.
Use the .fromkeys() class method:
dayDict = dict.fromkeys(weekList, 0)
It builds a dictionary using the elements from the first argument (a sequence) as the keys, and the second argument (which defaults to None) as the value for all entries.
By it's very nature, this method will reuse the value for all keys; don't pass it a mutable value such as a list or dict and expect it to create separate copies of that mutable value for each key. In that case, use a dict comprehension instead:
dayDict = {d: [] for d in weekList}
Apart from dict.fromkeys you can also use dict-comprehension,
but fromkeys() is faster than dict comprehensions:
In [27]: lis = ['a', 'b', 'c', 'd']
In [28]: dic = {x: 0 for x in lis}
In [29]: dic
Out[29]: {'a': 0, 'b': 0, 'c': 0, 'd': 0}
For 2.6 and earlier:
In [30]: dic = dict((x, 0) for x in lis)
In [31]: dic
Out[31]: {'a': 0, 'b': 0, 'c': 0, 'd': 0}
timeit comparisons:
In [38]: %timeit dict.fromkeys(xrange(10000), 0) # winner
1000 loops, best of 3: 1.4 ms per loop
In [39]: %timeit {x: 0 for x in xrange(10000)}
100 loops, best of 3: 2.08 ms per loop
In [40]: %timeit dict((x, 0) for x in xrange(10000))
100 loops, best of 3: 4.63 ms per loop
As mentioned in comments by @Eumiro and @mgilson it is important to note that fromkeys() and dict-comprehensions may return different objects if the values used are mutable objects:
In [42]: dic = dict.fromkeys(lis, [])
In [43]: [id(x) for x in dic.values()]
Out[43]: [165420716, 165420716, 165420716, 165420716] # all point to a same object
In [44]: dic = {x: [] for x in lis}
In [45]: [id(x) for x in dic.values()]
Out[45]: [165420780, 165420940, 163062700, 163948812] # unique objects
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With