0

I think I do not understand how the .remove() method works in Python.

I have this snippet. The point of the b variable is to have an untouched copy of the a list in every iteration, but it is not working as I expected:

a = [0, 1, 2, 3, 4, 5]

for i in a:
    b = a.copy()
    a_i = b.remove(i)
    print(a_i)

I would expect the following outcome:

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

And instead I get:

None
None
None
None
None

Where is my misconception?

NOTE: I need an answer in a for loop format because this is a simplification of a bigger part of my code.

EDIT: The original version of the snippet had a b = a line instead of b = a.copy(). I corrected that (thanks) but I am still getting an array of None's.

pypau
  • 79
  • 1
  • 11
  • 2
    `while a: a_i = a.pop(0)`. Your approach does not work since `.remove()` returns `None` and you are modifying the list you are iterating over. – Klaus D. Aug 10 '23 at 11:00
  • 1
    `b = a` doesn't create a copy of the list. Any changes to `b` will also affect `a`. `b = a[:]` will create a copy. – interjay Aug 10 '23 at 11:05
  • @KlausD. Why is `a_i = b.remove(i)` returning `None`? I would expect `a_i` to be a list but with only the `i` item removed. – pypau Aug 10 '23 at 11:05
  • 1
    "The point of the b variable is to have an untouched copy of the a" no, that's not how [names work](https://nedbatchelder.com/text/names.html) – roganjosh Aug 10 '23 at 11:06
  • 1
    Assigning `a` to `b` does not cause a copy of `a` to be created. All it does is create a new reference to the existing list. Any change made to that list is visible through both of the variables that reference it. If you want to copy it, use `b = a.copy()`, or `b = a[:]`, or `b = list(a)`, etc. etc. There are lots of ways to copy a list. Simple assignment isn't one of them. – Tom Karzes Aug 10 '23 at 11:06
  • @interjay @roganjosh @Tom Karzes thanks, I changed that line to `b = a.copy()` but I am still getting an array of `None`'s, I still have another error in my code. – pypau Aug 10 '23 at 11:10
  • `remove()` removes the first instance of a value. It does not make sense to return the value since you already have the value. `pop()` returns and removes an item b y index. – Klaus D. Aug 10 '23 at 11:36

1 Answers1

1

Consider this answer: https://stackoverflow.com/a/10665602/21445669

Seems like the issue comes from removing elements of something you are iterating over. Probably assigning a to b doesn't create an independent object like you would expect due to reference semantics.

Try including this: b = a.copy() instead of b = a.

Furthermore - the return value of the .remove() method is None! You actually want to print(b) in the line after b.remove(i)

mkranj
  • 144
  • 8
  • 1
    This is one of the issues, but it will still print `None`. – interjay Aug 10 '23 at 11:07
  • 1
    Updated answer with the notion that you're actually assigning the return value of the remove() method, which is None. Instead of the current value of b. – mkranj Aug 10 '23 at 11:09
  • See Return value in docs: https://python-reference.readthedocs.io/en/latest/docs/list/remove.html – mkranj Aug 10 '23 at 11:11
  • thanks, `print(a_i)` was actually the part that was wrong and `print(b)` solved it. – pypau Aug 10 '23 at 11:14