Here is the code that burned me today. I'm re-writing my Sudoku solver to make it more "Pythonic" -- it was my first Python project, and the old code looks like translated C :lol: -- anyways, at one point, I need a dictionary to hold the possible locations in a row, column, or cell of each of the values 1 .. 9. Here is a simplified version of the first attempt:

d = dict().fromkeys(range(1,10), [])
for i in range(1,10):
    for j in range(1,10):
        if (i in possibles[coords[j]]):
           d[i].append(coords[j])

to my shock, d became monstrously huge! :twisted:

That led to this test:

d = dict().fromkeys(range(1,10), [])
d[1].append(2)
print d

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

Whereas

d = dict()
for i in range(1,10):
    d[i] = []
d[1].append(2)
 print d

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

Moral: fromkeys() doesn't initialize all keys to the same value; it initializes all keys to the same object.

In other words, don't use fromkeys(list, mutable_object) unless you really really want all keys to point to the exact same entry. :rolleyes:

Jeff

Comments
Clever observation

Thanks Jeff, good observation! To bad the Python help never mentions that! If you insist on using fromkeys() you could use a tuple, adding two tuples forms a new tuple and there is no problem:

d = dict().fromkeys(range(1,10), ())

print d  # {1: (), 2: (), 3: (), 4: (), 5: (), 6: (), 7: (), 8: (), 9: ()}
print id(d[1]), id(d[2]), id(d[3])  # 10948656 10948656 10948656  same object!

# works with a tuple, since adding two tuples creates a new tuple object
d[1] += (2,)

print d  # {1: (2,), 2: (), 3: (), 4: (), 5: (), 6: (), 7: (), 8: (), 9: ()}
This question has already been answered. Start a new discussion instead.