In the first example, the references in both positions of the list are pointing to the exact same dictionary. The correct way to do it is:
a = [{} for x in range(2)]
The second example is different:
a = [0] * 2
The number zero is copied across the list, but if you reassign the value on one of the positions that contain it, you'll simply copy a new number on the given index.
The key point is that in the first example the dictionary is a mutable object, whereas a number is not, and besides in the first example you performed an operation that mutated the dictionary, whereas in the second example you just reassigned the value in the list.