2

I just got got by a gotcha. This code acts as you would expect:

keys = range(8)

DICT={}
for k in keys:
    DICT[k] = []
print DICT
#returns
#{0: [], 1: [], 2: [], 3: [], 4: [], 5: [], 6: [], 7: []}

DICT[1].append('mkay')
print DICT
#returns
#{0: [], 1: ['mkay'], 2: [], 3: [], 4: [], 5: [], 6: [], 7: []}

But if I initialize the dictionary differently, the appending behavior is totally different:

DICT = dict(zip(keys,[[]]*len(keys)))
print DICT
#returns
#{0: [], 1: [], 2: [], 3: [], 4: [], 5: [], 6: [], 7: []}

So it looks the same. But it's not:

DICT[1].append('mkay')
print DICT
#returns
#{0: ['mkay'], 1: ['mkay'], 2: ['mkay'], 3: ['mkay'], 4: ['mkay'], 5: ['mkay'], 6: ['mkay'], 7: ['mkay']}

Does anyone know what's going on here? Thought I'd post this as well for anyone else who might get got by it.

Wapiti
  • 1,851
  • 2
  • 20
  • 40
  • 1
    Nothing mysterious. By multiplying `[[]]` with `len(keys)` you have created a list of lists that all of them point to same object. – Mazdak Apr 28 '16 at 23:01
  • 1
    See http://stackoverflow.com/a/36452923/2201041 for an answer that made it more clear to me. –  Apr 28 '16 at 23:01

1 Answers1

1

Every value in the dictionary refers to the same list, because of [[]]*len(keys). That says "create a list, and copy the reference to it len(keys) times".

Jay Kominek
  • 8,674
  • 1
  • 34
  • 51
  • I see. So `len(keys)` pointers are going to the same list. I assumed it just made `len(keys)` different lists! – Wapiti Apr 28 '16 at 23:05