这种在列表中交换值的方式是否使用 Python 中的额外内存?

Does this way of swapping values in list use extra memory in Python?

在列表中交换值的常用方法是使用临时变量。

temp = l[i]
l[i] = l[j]
l[j] = temp

但是在 python 你可以这样做:

l[i], l[j] = l[j], l[i]

第二种方法如何工作?这是完全相同的过程吗?它使用更少/更多内存吗?

import dis


def swap_using_temp(a, b):
    temp = a
    a = b
    b = temp


def swap_using_unpacking(a, b):
    a, b = b, a

swap_using_unpacking不需要额外的内存。

解释: 如果您使用 dis module of both the function described then you will see that in swap_using_unpacking there is a bytecode instruction ROT_TWO 反汇编代码,它交换堆栈的 2 个最顶层元素(不需要第三个变量,因此不会消耗额外的内存)。



dis.dis(swap_using_unpacking)

 11           0 LOAD_FAST                1 (b)
              2 LOAD_FAST                0 (a)
              <b>4 ROT_TWO</b>
              6 STORE_FAST               0 (a)
              8 STORE_FAST               1 (b)
             10 LOAD_CONST               0 (None)
             12 RETURN_VALUE

dis.dis(swap_using_temp)

  5           0 LOAD_FAST                0 (a)
              2 STORE_FAST               2 (temp)

  6           4 LOAD_FAST                1 (b)
              6 STORE_FAST               0 (a)

  7           8 LOAD_FAST                2 (temp)
             10 STORE_FAST               1 (b)
             12 LOAD_CONST               0 (None)
             14 RETURN_VALUE

你问错问题了。您没有使用汇编语言,而是 Python,因此您不必担心一些额外的字节。 Python 中真正重要的是可读性。

无论如何,这两个版本的内部实现方式应该或多或少相同,除了第一个版本创建了一个额外的标识符。它被明确命名为 temp,因此 只要您不在该范围内使用它,它就不会带来任何实际问题。

如果您使用 linting 环境警告您可能出现的问题(您应该做什么...),您必须意识到重用隐藏相同名称的变量名称在外部范围内,虽然在语言观点上完全正确,但会发出一些警告。但是因为你不应该在本地范围之外使用 temp 标识符(可读性......)所以它也不应该成为问题。

所以这更多的是品味问题。如果你或你的队友经常使用其他不允许多重赋值的语言,第一种方式会更自然。如果你主要使用 Python,第二种方式是恕我直言,more pythonic 因为它避免了在本地范围内添加不必要的标识符。但正如我已经说过的,没有什么比品味更重要的了...