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

vegaseat commented: Clever observation +5

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: ()}``````
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.