在 Python 中,我看到使用这种语法交换了两个变量值:
left, right = right, left
这是否被认为是交换两个变量值的标准方法,还是有一些其他方法可以按照惯例最常交换两个变量?
在 Python 中,我看到使用这种语法交换了两个变量值:
left, right = right, left
这是否被认为是交换两个变量值的标准方法,还是有一些其他方法可以按照惯例最常交换两个变量?
Python 从左到右计算表达式。请注意,在评估分配时,右侧先于左侧评估。
这意味着表达式的以下内容a,b = b,a
:
b,a
是求值的,也就是说,在内存中创建了两个元素的元组。这两个元素是由标识符b
和指定的对象a
,它们在程序执行期间遇到指令之前就已经存在。a
分配给元组的第一个元素(这是在交换之前以前是bb
的对象,因为它有 name )b
被分配给元组的第二个元素(这是在交换之前以前是 aa
的对象,因为它的标识符是)这种机制有效地交换了分配给标识符的对象a
和b
所以,回答你的问题:是的,这是在两个对象上交换两个标识符的标准方法。
顺便说一句,对象不是变量,它们是对象。
这是交换两个变量的标准方法,是的。
我知道交换变量的三种方法,但a, b = b, a
最简单。有
x = x ^ y
y = y ^ x
x = x ^ y
或者简而言之,
x ^= y
y ^= x
x ^= y
w = x
x = y
y = w
del w
x, y = y, x
我不会说这是一种标准的交换方式,因为它会导致一些意想不到的错误。
nums[i], nums[nums[i] - 1] = nums[nums[i] - 1], nums[i]
nums[i]
会先修改再影响第二个变量nums[nums[i] - 1]
。
不适用于多维数组,因为这里使用了引用。
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)
为了解决eyquem解释的问题,您可以使用该copy
模块通过函数返回一个包含值的(反转)副本的元组:
from copy import copy
def swapper(x, y):
return (copy(y), copy(x))
与 a 相同的功能lambda
:
swapper = lambda x, y: (copy(y), copy(x))
然后,将它们分配给所需的名称,如下所示:
x, y = swapper(y, x)
注意:如果您愿意,可以导入/使用deepcopy
而不是copy
.
该语法是交换变量的标准方法。但是,在处理被修改然后在交换的后续存储元素中使用的元素时,我们需要注意顺序。
使用带有直接索引的数组很好。例如:
def swap_indexes(A, i1, i2):
A[i1], A[i2] = A[i2], A[i1]
print('A[i1]=', A[i1], 'A[i2]=', A[i2])
return A
A = [0, 1, 2, 3, 4]
print('For A=', A)
print('swap indexes 1, 3:', swap_indexes(A, 1, 3))
给我们:
('For A=', [0, 1, 2, 3, 4])
('A[i1]=', 3, 'A[i2]=', 1)
('交换索引 1, 3 :', [0, 3, 2, 1, 4])
但是,如果我们改变左边的第一个元素并在左边的第二个元素中使用它作为索引,这会导致错误的交换。
def good_swap(P, i2):
j = P[i2]
#Below is correct, because P[i2] is modified after it is used in P[P[i2]]
print('Before: P[i2]=', P[i2], 'P[P[i2]]=', P[j])
P[P[i2]], P[i2] = P[i2], P[P[i2]]
print('Good swap: After P[i2]=', P[i2], 'P[P[i2]]=', P[j])
return P
def bad_swap(P, i2):
j = P[i2]
#Below is wrong, because P[i2] is modified and then used in P[P[i2]]
print('Before: P[i2]=', P[i2], 'P[P[i2]]=', P[j])
P[i2], P[P[i2]] = P[P[i2]], P[i2]
print('Bad swap: After P[i2]=', P[i2], 'P[P[i2]]=', P[j])
return P
P = [1, 2, 3, 4, 5]
print('For P=', P)
print('good swap with index 2:', good_swap(P, 2))
print('------')
P = [1, 2, 3, 4, 5]
print('bad swap with index 2:', bad_swap(P, 2))
('For P=', [1, 2, 3, 4, 5])
('之前:P[i2]=', 3, 'P[P[i2]]=', 4)
('好的交换: After P[i2]=', 4, 'P[P[i2]]=', 3)
('good swap with index 2:', [1, 2, 4, 3, 5])
('Before: P[i2]=', 3, 'P[P[i2]]=', 4)
('Bad swap: After P[i2]=', 4, 'P[P[i2]]= ', 4)
('bad swap with index 2:', [1, 2, 4, 4, 3])
坏交换是不正确的,因为 P[i2] 是 3,我们期望 P[P[i2]] 是 P[3]。但是P[i2]先变成了4,所以后面的P[P[i2]]变成了P[4],覆盖的是第4个元素而不是第3个元素。
上述场景用于排列。一个更简单的好交换和坏交换将是:
#good swap:
P[j], j = j, P[j]
#bad swap:
j, P[j] = P[j], j
您可以组合元组和XOR交换: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))
或者
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))
使用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))
输出:
Before swapping: x = 10 , y = 20
After swapping: x = 20 , y = 10