when a python list iteration is and is not a reference

后端 未结 3 718
野的像风
野的像风 2021-01-14 04:07

Could someone please offer a concise explanation for the difference between these two Python operations in terms of modifying the list?

demo = [\"a\", \"b\",         


        
相关标签:
3条回答
  • 2021-01-14 04:20

    The loop variable d is always a reference to an element of the iterable object. The question is not really a matter of when or when isn't it a reference. It is about the assignment operation that you are performing with the loop.

    In the first example, you are rebinding the original reference of an element in the object, with another reference to an empty string. This means you don't actually do anything to the value. You just assign a new reference to the symbol.

    In the second example, you are performing an indexing operation and assigning a new reference to the value at that index. demo remains the same reference, and you are replacing a value in the container.
    The assignment is really the equivalent of: demo.__setitem__(c, "")

    a = 'foo'
    id(a)  # 4313267976
    a = 'bar'
    id(a)  # 4313268016
    
    l = ['foo']
    id(l)  # 4328132552
    l[0] = 'bar'
    id(l)  # 4328132552
    

    Notice how in the first example, the object id has changed. It is a reference to a new object. In the second one, we index into the list and replace a value in the container, yet the list remains the same object.

    0 讨论(0)
  • 2021-01-14 04:22

    In the first example, the variable d can be thought of a copy of the elements inside the list. When doing d = "", you're essentially modifying a copy of whatever's inside the list, which naturally won't change the list.

    In the second example, by doing range(len(demo)) and indexing the elements inside the list, you're able to directly access and change the elements inside the list. Therefore, doing demo[c] would modify the list.

    If you do want to directly modify a Python list from inside a loop, you could either make a copy out the list and operate on that, or, preferably, use a list comprehension.

    So:

    >>> demo = ["a", "b", "c"]
    >>> test = ["" for item in demo]
    >>> print test
    ["", "", ""]
    
    >>> demo2 = [1, 5, 2, 4]
    >>> test = [item for item in demo if item > 3]
    >>> print test
    [5, 4]
    
    0 讨论(0)
  • 2021-01-14 04:22

    When you do d = <something> you are making the variable d refer to <something>. This way you can use d as if it was <something>. However, if you do d = <something else>, d now points to <something else> and no longer <something> (the = sign is used as the assignment operator). In the case of demo[c] = <something else>, you are assigning <something else> to the (c+1)th item in the list.

    One thing to note, however, is that if the item d has self-modifying methods which you want to call, you can do

    for d in demo:
        d.<some method>()
    

    since the list demo contains those objects (or references to the objects, I don't remember), and thus if those objects are modified, the list is modified too.

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