4

I have a list and I need to swap the 1st element in the list with the maximum element in the list.

But why does code 1 work while code 2 doesn't:

code 1:

a = list.index(max(list))
list[0], list[a] = list[a], list[0]

code 2:

list[0], list[list.index(max(list))] = list[list.index(max(list))], list[0]

I thought Python would first evaluate the right-hand side before assigning it to the names on the left?

3
  • 1
    I'm a little puzzled over the aggressive downvoting over this question. It is indeed puzzling behaviour if you don't know what is going on with the evaluation order of the assignment targets. Commented Jan 13, 2015 at 22:02
  • @MartijnPieters Exactly, that's why I was really surprised about how people behave, just because this poor guy has 10 of reputation, and it's for sure new to programming and to this website. Commented Jan 13, 2015 at 22:05
  • @MartijnPieters Could be, but I think that people are downvoting due to the lack of research. Commented Jan 13, 2015 at 22:05

1 Answer 1

5

Python stores results in multiple targets from left to right, executing the assignment target expression in that order.

So your second version essentially comes down to this:

temp = list[list.index(max(list))],list[0]
list[0] = temp[0]
list[list.index(max(list))] = temp[1]

Note that the list.index(max(list)) is executed after list[0] was altered, and that's where you just stored the maximum value.

This is documented in the Assignment statements documenation:

  • If the target list is a comma-separated list of targets: The object must be an iterable with the same number of items as there are targets in the target list, and the items are assigned, from left to right, to the corresponding targets.

From there on out it is as if each target is a single target, so the documentation that follows applies from left to right to each target:

Assignment of an object to a single target is recursively defined as follows.

[...]

  • If the target is a subscription: The primary expression in the reference is evaluated. It should yield either a mutable sequence object (such as a list) or a mapping object (such as a dictionary). Next, the subscript expression is evaluated.

If you changed the order of assignments your code would work:

list[list.index(max(list))], list[0] = list[0], list[list.index(max(list))]

because now list[list.index(max(list))] is assigned to first.

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

1 Comment

In other words, list[list.index(max(list))], list[0]=list[0],list[list.index(max(list))] works as expected.

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.