1

I'm trying to understand the functionality of the clear() function in Python. I noticed that when I clear a list variable that was used to append an array to an existing list variable in Python, it seems to retroactively alter the data placed into the variable.

Take for example the below code:

numbers = [[1, 2, 3]]
newNumberList = [4, 5, 6]
numbers.append(newNumberList)
newNumberList.clear()

I would assume that numbers should contain the values: [[1,2,3], [4,5,6]], seeing as the clear() function used on newNumberList took place after it was appended to numbers.

However,

the value for numbers instead becomes: [[1, 2, 3], []], Despite clear() seemingly never interacting with the variable numbers.

Interesting to also note; reinitializing newNumberList instead of using clear() like so:

newNumberList = []

does not alter the variable numbers, and does allow the value of numbers to end up being: [[1, 2, 3], [4, 5, 6]]

I'm learning Python and am 99% sure there is an obvious answer to this that is staring me in the face, but any assistance with this question I have would be greatly appreciated.

Olivier Melançon
  • 21,584
  • 4
  • 41
  • 73
Dilemma
  • 11
  • 1
  • Also related: https://stackoverflow.com/q/71712086/2745495 – Gino Mempin Jan 03 '23 at 23:41
  • Welcome to Stack Overflow. You understand the functionality of `.clear` perfectly. The issue is the functionality **of `.append`**. It **does not** copy anything, so `numbers` contains **the list itself** named `newNumberList`. If you clear it, then of course that change is also seen in `numbers`. It is the same as if you put a bomb into a bag and then the bomb explodes - the bag contains an exploding bomb, because you put **that** bomb into the bag, you didn't make a copy of it. – Karl Knechtel Jan 03 '23 at 23:57
  • A ~~picture~~ interactive visualization is word a ~~thousand~~ million words: https://pythontutor.com/visualize.html#code=numbers%20%3D%20%5B%5B1,%202,%203%5D%5D%0AnewNumberList%20%3D%20%5B4,%205,%206%5D%0Anumbers.append%28newNumberList%29%0AnewNumberList.clear%28%29&cumulative=false&curInstr=4&heapPrimitives=false&mode=display&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false – Alexander Jan 04 '23 at 00:00
  • This is an extremely common conceptual issue with many common duplicates questions of varying levels of specificness - you have already been referred to a not-quite-accurate general one, and a surprisingly specific one that probably doesn't need to exist separately. I am leading a project to, among other things, help decide what the "canonical" versions of these sorts of questions should be, which questions are distinct and valuable to consider separately, what questions can/should be generalized, what's **missing**, etc. – Karl Knechtel Jan 04 '23 at 00:00

1 Answers1

2

The comments are pointing you in the right direction. Once you understand the issue, the following code snippet illustrates a simple approach to avoiding it while keeping with your original example:

numbers = [[1, 2, 3]]

newNumberList = [4, 5, 6]

numbers.append(newNumberList.copy())  # shallow copy decouples lists

newNumberList.clear()

print(numbers)

Output:

[[1, 2, 3], [4, 5, 6]]

Note: The shallow copy works in this case because numbers in the list you are appending are immutable. If you were appending a list of lists, for example, then a shallow copy would be insufficient and a deep copy would be needed. The copy standard library has a function, deepcopy for this purpose.

rhurwitz
  • 2,557
  • 2
  • 10
  • 18