3

I am fairly new to Python, and was recently surprised by the following behavior:

If I have a list and remove an element by value:

lst=[1,2,3,4,5,6]
lst.remove(3)
print(lst)

I get the expected result

[1,2,4,5,6]

If I type an indexed list, I get the expected result:

type(lst[2:])
list

But if I apply a list method to an indexed list, I do not get list modified in place as I expect.

lst=[1,2,3,4,5,6]
#type(lst[2:])
lst[2:].remove(3)
print(lst)
[1,2,3,4,5,6]

Is this because the indexed list is not actually the same list as the original list (from the perspective of the .remove() method?

Kokomodo
  • 81
  • 1
  • 7
  • 4
    `lst[2:]` copies the array, `.remove(3)` removes from the copy, so the original isn't ever changed – Nick is tired Apr 08 '20 at 15:05
  • 2
    @Nick *the list – Klaus D. Apr 08 '20 at 15:07
  • @guidot No. `list.remove` method returns `None`. – Boseong Choi Apr 08 '20 at 15:11
  • https://stackoverflow.com/questions/26766587/removing-item-from-list-causes-the-list-to-become-nonetype – Kokomodo Apr 08 '20 at 15:15
  • If you using python 3.8+, `(lst := lst[2:]).remove(3)` will work. But I recommend to write by two lines. `lst = lst[2:]` and `lst.remove(3)`. – Boseong Choi Apr 08 '20 at 15:15
  • Thanks @Nick (and others). I'm a little caught off guard that lst[2:] is not simply pointing to the original list. I'll see if I can find more a more detailed reference on the function of list methods. Someone else asked a similar question five years ago, but from a pragmatic standpoint. I understand (thanks to the answers) how to manage this practically, but, I would like to understand the issue in depth. Does .remove() make a copy of any list it modifies and then overwrite the original list? – Kokomodo Apr 08 '20 at 15:23
  • @Kokomodo No, it edits it in place, you can check by using the built in `id` function to check if the id of the list changes – Nick is tired Apr 08 '20 at 15:26
  • Related: [Slicing a list in Python without generating a copy](https://stackoverflow.com/questions/5131538/slicing-a-list-in-python-without-generating-a-copy) ... [Does a slicing operation give me a deep or shallow copy?](https://stackoverflow.com/questions/19068707/does-a-slicing-operation-give-me-a-deep-or-shallow-copy) ... [slicings](https://docs.python.org/dev/reference/expressions.html#slicings). – wwii Apr 08 '20 at 15:48
  • There is a hint [here](https://docs.python.org/3/reference/datamodel.html#the-standard-type-hierarchy) in the sequences section. - `Sequences also support slicing: a[i:j] selects all items with index k such that i <= k < j. When used as an expression, a slice is a sequence of the same type. **This implies that the index set is renumbered so that it starts at 0**` – wwii Apr 08 '20 at 15:55

1 Answers1

1

1st[2:] is called slicing. It creates a copy of your list starting from the 2nd index to the last. So when you use the remove function it removes the element from the copy rather than the original. Use:

lst = lst[2:]
lst.remove(3)

This will give you the answer you expect to see.

Fabrice Jammes
  • 2,275
  • 1
  • 26
  • 39
A___
  • 83
  • 5