Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
366 views
in Technique[技术] by (71.8m points)

python - Tuple unpacking order changes values assigned

I think the two are identical.

nums = [1, 2, 0]    
nums[nums[0]], nums[0] = nums[0], nums[nums[0]]    
print nums  # [2, 1, 0]

nums = [1, 2, 0]    
nums[0], nums[nums[0]] = nums[nums[0]], nums[0]    
print nums  # [2, 2, 1] 

But the results are different.
Why are the results different? (why is the second one that result?)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Prerequisites - 2 important Points

  • Lists are mutable

    The main part in lists is that lists are mutable. It means that the values of lists can be changed. This is one of the reason why you are facing the trouble. Refer the docs for more info

  • Order of Evaluation

    The other part is that while unpacking a tuple, the evaluation starts from left to right. Refer the docs for more info


Introduction

when you do a,b = c,d the values of c and d are first stored. Then starting from the left hand side, the value of a is first changed to c and then the value of b is changed to d.

The catch here is that if there are any side effects to the location of b while changing the value of a, then d is assigned to the later b, which is the b affected by the side effect of a.


Use Case

Now coming to your problem

In the first case,

nums = [1, 2, 0]    
nums[nums[0]], nums[0] = nums[0], nums[nums[0]]    

nums[0] is initially 1 and nums[nums[0]] is 2 because it evaluates to nums[1]. Hence 1,2 is now stored into memory.

Now tuple unpacking happens from left hand side, so

nums[nums[0]] = nums[1] = 1   # NO side Effect. 
nums[0] = 2

hence print nums will print [2, 1, 0]

However in this case

nums = [1, 2, 0]   
nums[0], nums[nums[0]] = nums[nums[0]], nums[0]    

nums[nums[0]], nums[0] puts 2,1 on the stack just like the first case.

However on the left hand side, that is nums[0], nums[nums[0]], the changing of nums[0] has a side effect as it is used as the index in nums[nums[0]]. Thus

nums[0] = 2
nums[nums[0]] = nums[2] = 1  # NOTE THAT nums[0] HAS CHANGED

nums[1] remains unchanged at value 2. hence print nums will print [2, 2, 1]


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...