the first one, namely this
a = {}
b = []
for i in range(5) :
a['number'] = i
print(a)
doesn't do what you thing it does, first it add the key 'number'
with the value 0 to the dictionary a
and then print said dictionary, the second time it change the value associated with said key to 1
and once more print it, and soo on, is not creating a list or a new dictionary, it just print the current state of the dictionary
In the second one
for i in range(5) :
a['number'] = i
b.append(a)
you're appending to the list the same dictionary multiple times, and because what the list really store is a reference to the real object so you end with
[{'number': 4}, {'number': 4}, {'number': 4}, {'number': 4}, {'number': 4}]
and because they're are referencing the same object they of course will be same, and if you change one, you will see the change reflected on all entries in the list because once more the point to the same dictionary.
If you want that your list a to have different dictionary in it, you need to create a new one each time, like this for example:
b = []
for i in range(5) :
a = {'number': i}
b.append(a)
print(b)# [{'number': 0}, {'number': 1}, {'number': 2}, {'number': 3}, {'number': 4}]
or as a one liner with list comprehension
b = [{"number":i} for i in range(5)]