0

I have these lines of codes in a class in python:

1        for i in range(len(self.rg_nodes_range)):
2            tmp_rg = self.rg_nodes_range
3            tmp_rg.pop(i)

The value for self.rg_nodes_range is:

self.rg_nodes_range = [20, 21]

I expect that at the start of every loop, tmp_rg gets the value of [20, 21], and then in line 3, drop the corresponding index (i) from tmp_rg. For example, I want tmp_rg to be [21] at the end of the first iteration (when i==0), and to be [20] at the end of the second iteration (when i==1).

But it seems that it's not happening. I put some breakpoints and found out that in the first iteration, in line 3, tmp_rg and self.rg_nodes_range both change from [20, 21] to [21]. I double-checked it with these lines of code:

p = [1, 2, 3]
tp = p
tp.pop(0)
print(p)
print(tp)

and the output was (both p and tp changed):

[2, 3]
[2, 3]

Do you know what happens here? And how can I fix it to obtain my expected outputs? Thank you.

  • `tmp_rg` and `self.rg_nodes_range` are two names for a single list - in Python, assignment *never* makes a copy of anything. You'd need to write something like `tmp_rg = self.rg_nodes_range.copy()`. – jasonharper Feb 28 '22 at 21:56
  • You change the same object. Clone a list if you really need to. – Alexander B. Feb 28 '22 at 21:57

1 Answers1

0

It is not a pop() problem. The function is working as expected what you need to look for is deep vs shallow copy concept as in python when you assign a variable to other, it simply creates a shallow copy thus modifying original will modify the copy as well. However if you create a deep copy it will clone the objects allowing you to modify them separately.

So this:

p = [1, 2, 3]
tp = p
tp.pop(0)
print(p)
print(tp)

produces:

[2, 3]
[2, 3]

However this:

p = [1, 2, 3]
tp = p.copy()
tp.pop(0)
print(p)
print(tp)

produces

[1, 2, 3]
[2, 3]
Hamza
  • 5,373
  • 3
  • 28
  • 43
  • Since this is a 1-dimensional list, the distinction between deep and shallow copy is irrelevant. `p.copy()` makes a shallow copy. – Barmar Feb 28 '22 at 22:09
  • Seems more like a difference between a direct reference and a shallow copy. As @Barmar says above, `list.copy()` performs a shallow copy. You'd need `copy.deepcopy()` to get an actual deep copy, were that relevant – TheBiggerFish Feb 28 '22 at 22:10