beginner question about range with list and list

Dan Lenski dlenski at gmail.com
Fri Nov 24 00:28:19 EST 2006


erik gartz wrote:
> Doesn't {} allocate new memory for the
> dictionary each time? It almost appears as if the 2nd dictionary
> created overwrites the first one. Thanks for your help,
> Erik
>
> >>>
> >>> a = [[{}] *  3] * 2
> >>> a
> [[{}, {}, {}], [{}, {}, {}]]
> >>> for i in range(2):
> 	a[i][1] = {'x':i}
> >>> a
> [[{}, {'x': 1}, {}], [{}, {'x': 1}, {}]]
> >>>

You're right about both parts... sort of :-)

Each time that {} is EVALUATED, it allocates a brand new dictionary.
However you're using the list repetition operator (* n).  This operator
evaluates the list ONLY ONCE and then repeats that list n times.

The expression [{}]*3 will generate a list that contains the SAME
dictionary 3 times in a row.  The expression [[{}]*3]*2 will generate a
list that contains the SAME list twice in a row.  Thus, when you assign
to a[i][1], you are modifying a[0][1] and a[1][1], since a[0] and a[1]
are the same list.

The expression {'x':i} does indeed create a new dictionary each time it
is evaluated... however it gets assigned to the SAME list element each
time.

This is a fairly subtle point... if you want to make a new COPY of a
list (or other mutable object) rather than simply a new reference to
eat, you say a=b.copy() rather than just a=b.  The ability to have
multiple references to one object is general considered a feature in
most programming languages, once you get used to it!

If you want to generate a 2x3 array with each element a DISTINCT
dictionary belonging to a DISTINCT list, try this:

a = [[{} for j in range(3)] for i in range(2)]
for i in range(2):
  for j in range(3):
    a[i][j] = {'row': i, 'column': j}

Dan




More information about the Python-list mailing list