0

I want to go from list1 = [[x]] to list2 = [[x],[x,2]]. The second element of list2 should be created from the first element. I tried this:

list1 = [[1]]
list1.append(list1[0])
list1[1].append(2)
list2 = list1

But this results in:

list2=[[1, 2], [1, 2]]

and not what I actually wanted:

list2=[[1], [1, 2]]

as I wanted.

I guess that this is because when I append list1[0], this is not a copy of list1[0], but index 1 of list1 is still pointing to the same object.

How can I get around this?

ggorlen
  • 44,755
  • 7
  • 76
  • 106
Mencia
  • 848
  • 2
  • 11
  • 19

4 Answers4

3

Is this python 2 or 3? You'll have to actually copy the list, otherwise you're just appending a reference.

Python 2:

list1 = [[1]]
list1.append(list(list1[0]))
list1[1].append(2)

Or list.copy was explicitly added in version 3.3:

list1 = [[1]]
list1.append(list1[0].copy())
list1[1].append(2)
doggie_breath
  • 782
  • 1
  • 6
  • 21
3

Your list1.append(list1[0]) line appends an alias of the 0-th element, which is a list object, of list1 to itself. Now list1 looks like this in memory:

   [1] <-----+
    ^        |
    |        |
[index 0, index 1]

That is, there are two references to the same inner list at both index 0 and 1.

Then, list1[1].append(2) pushes 2 to this single list, making it:

   [1,2] <---+
    ^        |
    |        |
[index 0, index 1]

Finally, you add another reference to this whole structure: list2 = list1.

The result looks like:

         [1,2] <---+
          ^        |
          |        |
list1: [index 0, index 1] 
  ^ 
  |
list2

You've only created a total of one inner list and one outer list. Modifications done to list2 will affect list1, and modifications on either index of either reference list will affect both indexes of both references.

While the example you've provided is a bit contrived and the use case is unclear (you may not actually want to copy these lists, especially if they are complex objects, and it's not clear whether it's indended that list2 alias list1), you probably want something like:

list1 = [[1]]
list1.append(list1[0][:]) # copy using slice syntax
list1[1].append(2)
list2 = [x[:] for x in list1] # copy again using slice syntax and a list
                              # comprehension, assuming you don't want an alias
ggorlen
  • 44,755
  • 7
  • 76
  • 106
0
list1 = [[1]]
list1.append(list1[0].copy())
list1[1].append(2)
list2 = list1
print(list2)
Mayowa Ayodele
  • 549
  • 2
  • 11
0

You could do:

>>> lis=[[1]]
>>> lis
[[1]]
>>> lis.append([lis[0][0],2])
>>> lis
[[1], [1, 2]]
Saurav Saha
  • 745
  • 1
  • 11
  • 30