The Question :
358 people think this question is useful
In Python, I’ve seen two variable values swapped using this syntax:
left, right = right, left
Is this considered the standard way to swap two variable values or is there some other means by which two variables are by convention most usually swapped?
The Question Comments :
The Answer 1
419 people think this answer is useful
Python evaluates expressions from left to right. Notice that while
evaluating an assignment, the right-hand side is evaluated before the
left-hand side.
http://docs.python.org/3/reference/expressions.html#evaluation-order
That means the following for the expression a,b = b,a
:
- the right-hand side
b,a
is evaluated, that is to say a tuple of two elements is created in the memory. The two element are the objects designated by the identifiers b
and a
, that were existing before the instruction is encoutered during an execution of program
- just after the creation of this tuple, no assignement of this tuple object have still been made, but it doesn’t matter, Python internally knows where it is
- then, the left-hand side is evaluated, that is to say the tuple is assigned to the left-hand side
- as the left-hand side is composed of two identifiers, the tuple is unpacked in order that the first identifier
a
be assigned to the first element of the tuple (which is the object that was formely b before the swap because it had name b
)
and the second identifier b
is assigned to the second element of the tuple (which is the object that was formerly a before the swap because its identifiers was a
)
This mechanism has effectively swapped the objects assigned to the identifiers a
and b
So, to answer your question: YES, it’s the standard way to swap two identifiers on two objects.
By the way, the objects are not variables, they are objects.
The Answer 2
112 people think this answer is useful
That is the standard way to swap two variables, yes.
The Answer 3
40 people think this answer is useful
I know three ways to swap variables, but a, b = b, a
is the simplest. There is
XOR (for integers)
x = x ^ y
y = y ^ x
x = x ^ y
Or concisely,
x ^= y
y ^= x
x ^= y
Temporary variable
w = x
x = y
y = w
del w
Tuple swap
x, y = y, x
The Answer 4
25 people think this answer is useful
I would not say it is a standard way to swap because it will cause some unexpected errors.
nums[i], nums[nums[i] - 1] = nums[nums[i] - 1], nums[i]
nums[i]
will be modified first and then affect the second variable nums[nums[i] - 1]
.
The Answer 5
6 people think this answer is useful
Does not work for multidimensional arrays, because references are used here.
import numpy as np
# swaps
data = np.random.random(2)
print(data)
data[0], data[1] = data[1], data[0]
print(data)
# does not swap
data = np.random.random((2, 2))
print(data)
data[0], data[1] = data[1], data[0]
print(data)
See also Swap slices of Numpy arrays
The Answer 6
-1 people think this answer is useful
To get around the problems explained by eyquem, you could use the copy
module to return a tuple containing (reversed) copies of the values, via a function:
from copy import copy
def swapper(x, y):
return (copy(y), copy(x))
Same function as a lambda
:
swapper = lambda x, y: (copy(y), copy(x))
Then, assign those to the desired names, like this:
x, y = swapper(y, x)
NOTE: if you wanted to you could import/use deepcopy
instead of copy
.
The Answer 7
-3 people think this answer is useful
You can combine tuple and XOR swaps: x, y = x ^ x ^ y, x ^ y ^ y
x, y = 10, 20
print('Before swapping: x = %s, y = %s '%(x,y))
x, y = x ^ x ^ y, x ^ y ^ y
print('After swapping: x = %s, y = %s '%(x,y))
or
x, y = 10, 20
print('Before swapping: x = %s, y = %s '%(x,y))
print('After swapping: x = %s, y = %s '%(x ^ x ^ y, x ^ y ^ y))
Using lambda:
x, y = 10, 20
print('Before swapping: x = %s, y = %s' % (x, y))
swapper = lambda x, y : ((x ^ x ^ y), (x ^ y ^ y))
print('After swapping: x = %s, y = %s ' % swapper(x, y))
Output:
Before swapping: x = 10 , y = 20
After swapping: x = 20 , y = 10