0

I have this small loop, which loops over some numbers, then loops over a list of list. If the number within the first loop is within the loop, it is removed. However, I noticed that this ie being removed from the list of list and not the list from withe loop. Code below

num_list = [[1,2,3,4,5], [1,2,3,4,5]]
for num in [1,2,3,4,5]:
    for pimp in num_list:
        if num in pimp:
            pimp.remove(num)
        print(pimp)

Yet, it works as expected in the following code:

for num in [1,2,3,4,5]:
    for pimp in [[1,2,3,4,5], [1,2,3,4,5]]:
        if num in pimp:
            pimp.remove(num)
        print(pimp)

What is the difference? What am I missing here?

BillyJo_rambler
  • 563
  • 6
  • 23
  • I am not sure I understand what you mean? I thought I was modifying 'pimp' and not the num_list? – BillyJo_rambler Jan 30 '19 at 20:55
  • In your second example, each iteration of the loop is creating it's own copy of `[[1,2,3,4,5], [1,2,3,4,5]]`. In the first example, you are iterating over `num_list` each time - which means you are modifying the lists in `num_list`. – AChampion Jan 30 '19 at 20:58
  • @Jean-FrançoisFabre I'm not sure this is the quite the same thing as the duplicate. Because the OP is not modifying the item they are iterating over... This is a list of lists. – AChampion Jan 30 '19 at 20:59
  • yes too trigger happy. Reopened. But now it's unclear :) – Jean-François Fabre Jan 30 '19 at 21:00
  • there is no difference, except that you're keeping the reference of the lists you removed as `num_list`. What do you want to achieve? make a copy of the lists if you don't want them altered. – Jean-François Fabre Jan 30 '19 at 21:02
  • I use num_list on different loops throughout my code, so I was not aware it was being altered. I assumed (being a noob) that by iterating over it and modiying 'pimp', I was only modifying 'pimp' and not the original list of lists. – BillyJo_rambler Jan 30 '19 at 21:04
  • Iterating over `num_list` means `pimp` is a reference to each list in `num_list`, so when you modify it you are changing the list in `num_list`. Create a copy if you don't want this side effect. – AChampion Jan 30 '19 at 21:18
  • Perfect, thanks for the advice. – BillyJo_rambler Jan 30 '19 at 21:21

1 Answers1

1

Currently when you do for pimp in num_list, you are iterating over the reference to your original list num_list. So you changes in the pimp are reflected in the original nested num_list. To avoid it, you need to create a deep copy of your num_list in your for loop. This can be done using deepcopy which creates a copy of nested lists including all sublists.

from copy import deepcopy

num_list = [[1,2,3,4,5], [1,2,3,4,5]]
for num in [1,2,3,4,5]:
    for pimp in deepcopy(num_list):
        if num in pimp:
            pimp.remove(num)
        print(pimp)

[2, 3, 4, 5]
[2, 3, 4, 5]
[1, 3, 4, 5]
[1, 3, 4, 5]
[1, 2, 4, 5]
[1, 2, 4, 5]
[1, 2, 3, 5]
[1, 2, 3, 5]
[1, 2, 3, 4]
[1, 2, 3, 4]
Sheldore
  • 37,862
  • 7
  • 57
  • 71