是否有标准化的方法在Python中交换两个变量?

Wil*_*mKF 310 python syntax swap conventions

在Python中,我看到使用这种语法交换了两个变量值:

left, right = right, left
Run Code Online (Sandbox Code Playgroud)

这被认为是交换两个变量值的标准方法,还是有一些其他方法可以按惯例最常交换两个变量?

eyq*_*uem 352

Python从左到右评估表达式.请注意,在评估分配时,右侧在左侧之前进行评估.

http://docs.python.org/3/reference/expressions.html#evaluation-order

这意味着以下表达式a,b = b,a:

  • b,a评估右侧,也就是说在内存中创建了两个元素的元组.两个元件是由标识符指定的对象ba,程序的执行期间,该指令被encoutered之前已存在
  • 在创建这个元组之后,仍然没有对这个元组对象进行任何分配,但是没关系,Python内部知道它在哪里
  • 然后,评估左侧,也就是说元组被分配到左侧
  • 由于左侧由两个标识符组成,因此将元组解包,以便将第一个标识符a分配给元组的第一个元素(这是因为它具有名称 而在交换之前为b的对象b)
    和第二标识符b被分配给元组的第二个元素(其是前身对象一个交换之前,因为它的标识符是a)

这种机制有效地交换了分配给标识符的对象ab

所以,回答你的问题:是的,这是在两个对象上交换两个标识符的标准方法.
顺便说一下,对象不是变量,它们是对象.

  • @Catbuilts 构造元组将占用一些额外的内存(可能比交换的 3 变量版本占用的内存更多),但由于唯一交换的内容是内存地址,因此绝对不会有太多额外的内存sense(可能是 24 个额外字节)。 (2认同)
  • @Catbuilts 我不确定,但了解 C++ 指针的工作原理可能会有所帮助。Python 尝试自动以最适合您的方式做事,而 C++ 实际上为您提供了以所有可能的正确和错误方式做事的所有选项,因此这是了解 Python 采用的方法的缺点的一个很好的起点。另请记住,拥有“64 位”操作系统意味着存储内存地址会占用 64 位内存 - 这是我获取“24 字节”数字的部分来源。 (2认同)
  • 很好的解释。只需添加一点,这就是为什么您还可以使用此方法重新排列任意数量的“变量”,例如 `a, b, c = c, a, b`。 (2认同)

Mar*_*ers 105

这是交换两个变量的标准方法,是的.


NoO*_*ere 35

我知道三种交换变量的方法,但a, b = b, a最简单.有

异或(对于整数)

x = x ^ y
y = y ^ x
x = x ^ y
Run Code Online (Sandbox Code Playgroud)

或者简洁地说,

x ^= y
y ^= x
x ^= y
Run Code Online (Sandbox Code Playgroud)

临时变量

w = x
x = y
y = w
del w
Run Code Online (Sandbox Code Playgroud)

元组交换

x, y = y, x
Run Code Online (Sandbox Code Playgroud)

  • XOR不会交换"变量".它交换整数变量.(或者正确实现XOR运算符的其他几种类型)此外,根据Rogalski的回答,Tuple Swap在解释器中进行了优化,实际上并没有反对它.简短,清晰,快速. (16认同)

小智 17

我不会说它是一种标准的交换方式,因为它会导致一些意外错误.

nums[i], nums[nums[i] - 1] = nums[nums[i] - 1], nums[i]
Run Code Online (Sandbox Code Playgroud)

nums[i]将首先修改然后影响第二个变量nums[nums[i] - 1].

  • @JacksonKelley 右侧的评估是安全的。在 `nums[i], nums[nums[i] - 1] = nums[nums[i] - 1], nums[i]` 中:问题是当 python 进行左侧赋值时,`nums[i] ]` 被更改,这会导致 `nums[nums[i] - 1]` 发生意外更改。你可以想象一开始你想要 `nums[1],nums[2] = nums[2],nums[1]`,但是在 `nums[1] = nums[2]` 运行之后,你不再有 `nums [2] = nums[1]`,而是得到 `nums[888] = nums[1]` 。 (4认同)
  • 您几乎在所有编程语言中都有问题,如果a依赖于b,反之亦然,使用swap(a,b)是不安全的。例如,swap(a,b)可以扩展为:var c = a,a = b,b = c。然后,最后一次赋值将使用新值“ a”来评估b的地址。 (2认同)
  • `nums[nums[i] - 1],nums[i] = nums[i],nums[nums[i] - 1]`。就能解决问题了。 (2认同)

giz*_*ole 6

不适用于多维数组,因为此处使用了引用。

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)
Run Code Online (Sandbox Code Playgroud)

另请参阅交换 Numpy 数组的切片