2

Can anyone explain to me why on test1, nums is [[0,0],[-1,-1],[0,0],[0,0]] but not on test2? as my understand python for xx in xxx is pretty much like for loop in any other language and take element by element. So what is different between using unpack in for loop and not? Thank you

test([[0,0],[0,0],[0,0],[0,0]])
test2([[0,0],[0,0],[0,0],[0,0]])
def test1(self, nums):
    ctn = 0
    for e in nums:
        ctn += 1
        u, v = e
        if ctn == 2:
            e[0] = e[1] = -1
    print(nums)  #[[0,0],[-1,-1],[0,0],[0,0]]

def test2(self, nums):
    ctn = 0
    for u, v in nums:
        ctn += 1
        if ctn == 2:
            u = v = -1
    print(nums)  #[[0,0],[0,0],[0,0],[0,0]]
1

4 Answers 4

2

The variables u and v are references to the elements in the sublist, without any reference to the sublist itself. When you change either value, it does not cause any side effects.

However, e is a reference to the sublist itself. When you index into e and change its values, you are performing an assignment in the sublist itself, and thus causes side effects (changing the value in the original list).

Sign up to request clarification or add additional context in comments.

8 Comments

u and e act as references to the items in the list, the way you've added emphasis might be misleading
so why e is a reference but u and v is "new" variable from list? i guess another way to say is why e is not something e = [0,0] that store the value from nums sublist?
@DillonDavis absolutely incorrect. There are no primitive types in Python. Everything is an object, and the evaluation strategy doesn't not change depending on the type of the object. See this question. Suffice it to say, Python is neither call by reference nor call by value. It is "call by sharing", although that is a little used term. This is the same evaluation strategy of most modern languages, e.g. Python, Java, Javascript, Ruby.
But it is very important to understand that whatever you call it, the evaluation strategy does not depend on the type of the object Another good link to read: nedbatchelder.com/text/names.html
"Copy on write" is totally irrelevant here. Not sure what you are getting at, nor what you code snippet is supposed to show. Note, small integers are cached, i.e., in Python int objects in the range -2-255 are singletons. That is an implementation detail, though, that shouldn't be relied upon. Anyway, "u and v do not reference into the list", I'm not sure what that's supposed to mean, but u and v are definitely references to the same object in the list.
|
1

Variable hold references in Python. That means that when you assign a mutable object (a list is) to a variable and change the object through that variable you change the original object. That is the reason why test1 does change the original list.

But when you assign to a variable, you do not change the object it previously refered, but only have it point to a new object. As you assign to u and v in test2 you change nothing in the original objects.


When you use e[0] = -1, you do not assign to variable e but actually modify the object pointed to by e

Comments

0

in the first function u, v =e do nothing,delete it i get the same answer

def test1(nums):
    ctn = 0
    k = []
    for e in nums:
        ctn += 1
        if ctn == 2:
            e[0] = e[1] = -1
    print(nums)

def test2(nums):
    ctn = 0
    for u, v in nums:
        ctn += 1
        if ctn == 2:
            u = v = -1
    print(nums)

Comments

-1

In test2, u and v are temporary copies of the original values in the list. Because they are copies, any changes you make to them will not be reflected in the original list.

1 Comment

They are not copies at all. If they were mutable, mutations would be reflected in the original list.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.