188

I have a = [1,2,3,4] and I want d = {1:0, 2:0, 3:0, 4:0}

d = dict(zip(q,[0 for x in range(0,len(q))]))

works but is ugly. What's a cleaner way?

Brad Koch
  • 19,267
  • 19
  • 110
  • 137
blahster
  • 2,043
  • 2
  • 14
  • 8

5 Answers5

258

dict((el,0) for el in a) will work well.

Python 2.7 and above also support dict comprehensions. That syntax is {el:0 for el in a}.

Tim McNamara
  • 18,019
  • 4
  • 52
  • 83
  • 3
    Generator expressions avoid the memory overhead of populating the whole list. – Tim McNamara Oct 06 '10 at 04:30
  • 22
    You should probably promote that comment into your actual answer. Also, from Python 2.7 and Python 3 you can do `{el:0 for el in a}`. (Feel free to add that into your answer as well.) – Zooba Oct 06 '10 at 04:37
219
d = dict.fromkeys(a, 0)

a is the list, 0 is the default value. Pay attention not to set the default value to some mutable object (i.e. list or dict), because it will be one object used as value for every key in the dictionary (check here for a solution for this case). Numbers/strings are safe.

Community
  • 1
  • 1
eumiro
  • 207,213
  • 34
  • 299
  • 261
  • 19
    the only pythonic way. – SilentGhost Oct 06 '10 at 07:47
  • 3
    This appears to be cleaner (for me at least), how does it compare to Tim's? – blahster Oct 06 '10 at 10:22
  • 5
    Tim's solution works for any default values (you can initialize the dictionary with an empty list or datetime object or anything). In my solution, you can initialize it only with immutable objects (int/float, string,...). It is more pythonic for your case (default value is 0) and very probably it is also faster. – eumiro Oct 06 '10 at 10:31
  • 2
    In python 3.4 `d = dict.fromkeys(set(a_list), [])` also works – semiomant Jul 06 '17 at 10:20
  • This is the way to do it no need for comprehensions everywhere – pouya Aug 17 '17 at 22:09
  • 5
    Didn't read the warning that if `0` is mutable (e.g. list or dict), you get into trouble, because it all refers to the same memory location. For this reason, the accepted answer is safer. – NumesSanguis Oct 25 '19 at 07:00
  • @NumesSanguis Exactly! Faced this issue while initializing this with a list. The same values are copied all over. – Rishab P Mar 18 '21 at 18:42
19

In python version >= 2.7 and in python 3:

d = {el:0 for el in a}
Andrey
  • 1,495
  • 17
  • 14
8

In addition to Tim's answer, which is very appropriate to your specific example, it's worth mentioning collections.defaultdict, which lets you do stuff like this:

>>> d = defaultdict(int)
>>> d[0] += 1
>>> d
{0: 1}
>>> d[4] += 1
>>> d
{0: 1, 4: 1}

For mapping [1, 2, 3, 4] as in your example, it's a fish out of water. But depending on the reason you asked the question, this may end up being a more appropriate technique.

intuited
  • 23,174
  • 7
  • 66
  • 88
5
d = dict([(x,0) for x in a])

**edit Tim's solution is better because it uses generators see the comment to his answer.

GWW
  • 43,129
  • 11
  • 115
  • 108