Mathews_M_J
Mathews_M_J

Reputation: 467

Trouble with editing items in list of lists

I wanted to a make a list of list using pythons and I know two methods to do it.

The first method is like so:

l = []
l_in = []
for j in range(2):
   l_in.append("1")
print l_in
for i in range(2):
   l.append(l_in)
print l

and the second method is:

l = []
for i in range(2):
   l.append([1]*2)
print l

Both these methods creates a list

l = [['1', '1'], ['1', '1']] 

I want to change only on element int this list say the (1,1) element. If I do

l[1][1] = "Something I want to replace with"

the element should be replaced. This works fine for the second method. But if I use the first method both (1,1) and (0,1) changes to "Something I want to replace with".

Can someone tell me why using the first method gives this output?

Upvotes: 0

Views: 80

Answers (1)

msvalkon
msvalkon

Reputation: 12077

It's because in the first method, in the second loop you are appending the same list twice.

for i in range(2):
    l.append(l_in)

Now whenever you're modifying an element in l, you are actually modifying elements in one list. An easy way to understand is to look at the values the builtin id() gives for the content of l.

>>> map(id, l)
[32750120, 32750120]

You can see that both elements in l share the same id (and the same memory address). They both refer to the same list l_in.

As Aशwini चhaudhary suggested, an easy fix is l.append(l_in[:]) where the [:] creates a copy of the list l_in.

l = []
l_in = []
for j in range(2):
   l_in.append("1")
print l_in
for i in range(2):
   l.append(l_in[:])
print l

You can also create lists of lists with list and generator comprehensions. Some examples below:

# empty lists..
>>> [[] for _ in range(4)]
[[], [], [], []]

# generator expression..
>>> list([] for _ in range(4))
[[], [], [], []]

# [1, 1] for each sublist.
>>> list([1, 1] for _ in range(4))
[[1, 1], [1, 1], [1, 1], [1, 1]]

Here's the help() on id():

Help on built-in function id in module __builtin__:

id(...)
    id(object) -> integer

    Return the identity of an object.  This is guaranteed to be unique among
    simultaneously existing objects.  (Hint: it's the object's memory address.)

Upvotes: 4

Related Questions