assignment operator about list in Python

后端 未结 4 786
野趣味
野趣味 2021-01-19 18:02

I am a beginner in Python, I cannot understand assignment operator clearly, for example:

list1 = [\"Tom\", \"Sam\", \"Jim\"]
list2 = list1

相关标签:
4条回答
  • 2021-01-19 18:53

    In your example the identifiers list1 and list2 are references to the same underlying object (just different names for the same thing).

    id() can be used to see if the same underlying object is being referenced.

    >>> list1 = ["Tom", "Sam", "Jim"]
    >>> list2 = list1
    >>> id(list1)
    44259368
    >>> id(list2)
    44259368
    

    To create a copy of the defined list use the [:] notation, or deepcopy as Matthew has mentioned. You'll notice that when this is done the location/id has changed.

    >>> list3 = list1[:]
    >>> id(list3)
    44280208
    

    About the id command:

    >>> help(id)
    Help on built-in function id in module __builtin__:
    
    id(...)
        id(object) -> integer
    
        Return the identity of an object.  This is guaranteed to be unique among
        simultaneously existing objects.  (Hint: it's the object's memory address.)
    
    0 讨论(0)
  • 2021-01-19 18:54

    BrenBarn is absolutely right about everything, but here is another way to look at it that might be easier to understand:

    Your first statement creates a list with those values, then makes list1 point to it. The second statement makes list2 point to exactly the same memory space as list1. (You can see this by running id on both of them after the second statement).

    At that point list1 and list2 are essentially both references to the same mutable list. When you change that list, list1 and list2 are still both referencing the same actual list and using either to access it will give you the same thing.

    I did a blog post about a related topic recently and Python Conquers the Universe also talks about a similar topic here.

    0 讨论(0)
  • 2021-01-19 18:59

    You're right, they aren't the same. Assignment to a bare name in Python (name = ...) is a different operation than assignment to anything else. In particular it is different from item assignment (name[0] = ...) and attribute assignment (name.attr = ...). They all use the equal sign, but the latter two are manipulable with hooks (__setitem__ and __setattr__), can call arbitrary code, and are generally under the control of the programmer. Assignment to a bare name is not under the control of the Python programmer. You can't affect what it does; it always just binds the right hand side to the name on the left hand side.

    This can be confusing, because people are used to thinking that the equals sign is what makes an "assignment". But in Python, in order to understand what operation is taking place, you really have to look on the left of the equals sign and see what kind of thing is being assigned to.

    0 讨论(0)
  • 2021-01-19 19:02

    BrenBam has a good explanation of what is going on. deepcopy a way to get around it:

    >>> from copy import deepcopy
    >>> list1 = ["Tom", "Sam", "Jim"]
    >>> list2 = deepcopy(list1)
    >>> list1[1] = "Sam's sister"
    >>> list1
    ['Tom', "Sam's sister", 'Jim']
    >>> list2
    ['Tom', 'Sam', 'Jim']
    

    Good programming style will make it rare to have to actually use deepcopy though.

    0 讨论(0)
提交回复
热议问题