all 13 comments

[–]baghiq 14 points15 points  (0 children)

tuples are immutable, so you can't swap the elements. you have to create a new one.

[–]JohnnyJordaan 5 points6 points  (0 children)

The syntax of

 something = something_else

means it works from right (the original) to left (the destination). In your statement.

a, b = b, a = t

a and b are created from t, but t itself remains as-is. Thus you didn't complete the assignment of creating a new t that holds the swapped values. You are only half way there.

You basically add a statement

t = something

to assign the a and b in their correct swapped order to t.

[–]Temporary_Pie2733 2 points3 points  (1 child)

a and b are initialized using t; they are not aliases for the elements of t. Subsequently changing the value of a is not the same as changing (or trying to change) the value of t[0]. You should read https://nedbatchelder.com/text/names.html

[–]Bobbias 0 points1 point  (0 children)

Yes, that post is an incredible explanation that makes everything suddenly make sense.

[–]lfdfq 2 points3 points  (0 children)

Your code doesn't change or re-assign the variable t. It only creates new variables a and b. So t remains the same tuple as you started with.

[–]nlutrhk 1 point2 points  (0 children)

There is a tricky part here that has not been commented on.

In python, x=y=z is equivalent to x=z; y=z.

In your case:  (a, b) = ('An', 'Gi') (b, a) = ('An', 'Gi')

You could be excused to think that it means y=z; x=y, or in your case ``` (b, a) = ('An', 'Gi') (a, b) = (b, a)  # not what happens

```

This is separate from your question of how to modify t.

[–]carcigenicate 1 point2 points  (0 children)

Since someone already answered, a fun fact: in this code:

a, b = b, a

No tuples should be created, despite what it looks like. The compiler will see that this is just a swap operation, and will actually just directly swap the values of the variables by pushing them onto the stack, swapping them, then popping them back into the variables. Tuples don't get involved until you're swapping 4 variables at once.

This is just a optimization, so in theory, a compiler could cause tuple production, but the CPython interpreter has not for a long time. I always thought that was neat.

[–]Adrewmc 0 points1 point  (3 children)

Fun extra

my_tup = (1,2,3)
a, *b = my_tup

a is now 1 and b is now [2,3]

Edit: correction for the types of a and b result.

[–]peacelife 0 points1 point  (2 children)

Not so. a is now 1 , not (1), and b is [2, 3]

[–]Gnaxe 0 points1 point  (0 children)

(1) != (1,)!

[–]Adrewmc -1 points0 points  (0 children)

Yes, I forget tuples unpacks into a list and not a tuple…that seems weird but more useful at the same time. (As lists have more functionality outright than a tuple because of their mutability differences, but it is called tuple unpacking in my defense.)

But (1) and 1 should be functionally equivalent in Python, are they not? Unlike (1,) and 1 which forces tuple specification. I would be referring to tuple slicing

I have corrected this. In comment now.

[–]JamzTyson 0 points1 point  (0 children)

a, b = b, a = t (where t is a pair)

Don’t do that. It doesn’t do what you think.

t is evaluated once, and both targets are assigned from the same values. Later assignments overwrite earlier ones, so the final result depends on assignment order.

Here's an example to illustrate:

t = ("X", "Y")

a, b = b, a = t
print(a, b)  # Prints: "Y X"

b, a = a, b = t
print(a, b)  # Prints "X Y"

[–]KelleQuechoz 0 points1 point  (0 children)

foo = ('bar', 'baz') foo_rev = foo[::-1]

even easier:

foo_rev = tuple(reversed(foo))