In the first version, you use the same empty list object as the value for both keys, so if you change one, you change the other, too.
Look at this:
>>> empty = []
>>> d = dict.fromkeys(range(2), empty)
>>> d
{0: [], 1: []}
>>> empty.append(1) # same as d[0].append(1) because d[0] references empty!
>>> d
{0: [1], 1: [1]}
In the second version, a new empty list object is created in every iteration of the dict comprehension, so both are independent from each other.
As to "why" fromkeys()
works like that - well, it would be surprising if it didn't work like that. fromkeys(iterable, value)
constructs a new dict with keys from iterable that all have the value value
. If that value is a mutable object, and you change that object, what else could you reasonably expect to happen?