-3

Set 2nd list equal to 1st list

first_lzt = ['room', 'floor', 'name']
second_lzt = first_lzt

remove() element from 2nd list.

second_lzt.remove('room')

The element surprisingly also gets removed from the 1st list. Why?

>>> first_lzt

['floor', 'name']

Is that supposed to happen? How can I make second_lzt independent without appending items into it?

Python 3.7.6


EDIT: expected object behavior.

str1 = "apple"
str2 = str1
str2 = str2 + "_pie"

>>> str1
"apple"
int1 = 3
int2 = int1
int2 += 4

>>> int1
3
Kermit
  • 4,922
  • 4
  • 42
  • 74
  • Copy the list instead. You're currently only assigning the reference, *the exact same reference*. Any mutation to one reference will reflect changes across all variables storing the same reference. [Copying operations](https://docs.python.org/3/library/copy.html) – Chase Jan 19 '21 at 16:52
  • 2
    Assignment does not make a copy of the list. You only have a single list object with 2 names pointing to it. – rdas Jan 19 '21 at 16:53
  • 1
    Does this answer your question? [Python modifying wrong list?](https://stackoverflow.com/questions/4337106/python-modifying-wrong-list) – Tugay Jan 19 '21 at 16:53
  • These are the *same list*, not two "associated" lists. This is always the semantics of assignment. Read the following: https://nedbatchelder.com/text/names.html – juanpa.arrivillaga Jan 19 '21 at 16:55
  • Is this behavior specific to lists? I feel like I haven't experienced this before. – Kermit Jan 19 '21 at 16:57
  • @HashRocketSyntax no, absolutely not. This is the semantics of the *assignment statement* always, it has nothing to do with type. Read the Ned Badtchelder link – juanpa.arrivillaga Jan 19 '21 at 16:59
  • sooo that link makes it seem like it is specific to lists. – Kermit Jan 19 '21 at 17:02
  • @HashRocketSyntax no it doesn't. What part about "Fact: Assignment never copies data." seems specific to lists? – juanpa.arrivillaga Jan 19 '21 at 17:03
  • read my OP edit – Kermit Jan 19 '21 at 17:03
  • 1
    strings are immutable - you can never mutate them in the first place – Chase Jan 19 '21 at 17:04
  • @HashRocketSyntax if you `print(int1)` it's still `3` as well. **Please just read the link** – juanpa.arrivillaga Jan 19 '21 at 17:04
  • @Chase **completely irrelevant** in this case. You can get the same exact behavior with lists: `list1 = [1,2,3]; list2 = list1; list1 + [4]; print(list1); print(list2)` – juanpa.arrivillaga Jan 19 '21 at 17:05
  • 1
    @juanpa.arrivillaga OP posted an example with strings – Chase Jan 19 '21 at 17:05
  • @Chase **the type of the items in the list are completely irrelevant**. The fact that `str` objects are immutable doesn't matter to the semantics of assignment, which never changes due to type. – juanpa.arrivillaga Jan 19 '21 at 17:06
  • @HashRocketSyntax you are not understanding. **Assignment never copies**. You can *always* re-assign a name to another object. Again, you get *the exact same behavior with lists*: `list1 = [3]; list2 = list1; list2 + [3]; print(list1)` – juanpa.arrivillaga Jan 19 '21 at 17:08
  • thanks for the explanations. at the end of the day, regardless of the inner workings of assignment, as an end user, this behavior feels inconsistent with the rest of the language. otherwise, i wouldn't be making this post. – Kermit Jan 19 '21 at 17:15
  • 1
    @HashRocketSyntax It is entirely consistent across the whole language. It is also the same exact semantics of most similar languages, e.g. Java, JS, Ruby etc etc Do you come from a C background? C and C++ work differently. – juanpa.arrivillaga Jan 19 '21 at 17:28

2 Answers2

1

To make a list independent, use .copy. For example:

first_lzt = ['room', 'floor', 'name']
second_lzt = first_lzt.copy()

Now, if you do second_lzt.remove("room") it will remove room from only the second list.

Kermit
  • 4,922
  • 4
  • 42
  • 74
The Pilot Dude
  • 2,091
  • 2
  • 6
  • 24
0

yes, its not creating a second list under the hood, like @Chase says you are referencing a variable to the list. Nothing more.

#Copy List Using Slicing Syntax

first_lzt = ['room', 'floor', 'name']
second_lzt = first_lzt[:]

watch your code in action

Avatazjoe
  • 465
  • 6
  • 13