1

I am trying to use Python term to explain why the following happens, can somebody explain why tmp becomes to [[1,2,3]] not stay as [[1,2]]?

arr = []
tmp = [1,2]
arr.append(tmp)
print arr # [[1,2]]
tmp.append(3)
print arr # [[1,2,3]]
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
idontknoooo
  • 261
  • 1
  • 3
  • 12
  • 4
    `arr.append(tmp)` does not copy the list referred to by `tmp`. It just adds another reference to the same list at the end of `arr`. So now `arr[0]` and `tmp` refer to the same object. – Steven Rumbalski Oct 29 '18 at 23:02
  • 1
    [immutable vs mutable types](https://stackoverflow.com/questions/8056130/immutable-vs-mutable-types) – John Oct 29 '18 at 23:07
  • This is just the basic semantics of simple Python assignment. Read https://nedbatchelder.com/text/names.html – juanpa.arrivillaga Oct 30 '18 at 00:48

3 Answers3

2

arr = [] is an empty list, and when you append tmp to it via:

tmp = [1, 2]
arr.append(tmp)

You are putting tmp in the arr list, thus giving you arr = [tmp] which can be expanded to arr = [[1,2]]. But the neat thing here is that you maintain a reference to to the list, [1,2] via the temp variable. Thus, when you append temp you are appending the same list that is in arr.

For a bit further clarification, just because you are appending tmp to arr doesn't mean that the resulting list [[1,2]] is all going to be one continuous block in memory. You are going to have the arr list and the first element of arr is going to be a pointer to the list tmp.

peachykeen
  • 4,143
  • 4
  • 30
  • 49
  • So append in python list is like copy by reference in C++ rather than copy by value? – idontknoooo Oct 30 '18 at 01:36
  • `append` appends the passed object onto the list and in your example above no copying is being done. The original `tmp` object is the one that is being added to the list, so when you change `tmp` you change the list that is now in `arr`. – peachykeen Oct 30 '18 at 02:39
1

All the comments are great ones.

arr.append(tmp)
print arr # [[1,2]]

As you can see, the result is NOT:

print arr # [1,2]

So, arr just holds the reference to tmp array. If my guess is write you are looking for:

 arr.extend(tmp)
 print arr # [1,2]

More on difference between append vs. extend list methods in python

azbarcea
  • 3,323
  • 1
  • 20
  • 25
0

That's because of both tmp and arr[0] points to the same object. Just check it here, step by step:

http://www.pythontutor.com/visualize.html

First print statement Second print statement

You can manually check it by using id built-in

>>> arr = []
>>> tmp = [1,2]
>>> arr.append(tmp)
>>> id(tmp)
4404123192
>>> id(arr[0])
4404123192
>>> assert id(tmp) == id(arr[0])
>>> tmp.append(3) # allocate more memory (if needs) and add '3' to object (list) with id 4404123192
>>> id(tmp)
4404123192
>>> id(arr[0])
4404123192
>>> print arr
[[1, 2, 3]]
Nikscorp
  • 381
  • 2
  • 8
  • " # allocate more memory " that is misleading, no new memory is allocated necessarily. Generally this is not a helpful way about thinking of things in Python – juanpa.arrivillaga Oct 30 '18 at 00:49
  • @juanpa.arrivillaga reason to write this comment was to show, that even on memory reallocation, both variables are kept pointing to the same object. There are some cases with other `append` semantics, for example like golang works with slices. – Nikscorp Oct 30 '18 at 01:26