11

在python中,当我将一个列表分配给另一个时,例如:

a = [1,2,3]
b = a

现在 b 和 a 指向同一个列表。现在考虑两个列表,

a = [1,2,3]
b = [4,5,6]
a,b = b,a

现在,它们如何像任何其他数据类型一样被交换并且最终不会都指向同一个列表?

4

3 回答 3

11

看起来 Python 在内部交换了这些项目。检查这个程序

a, b = [1, 2], [2, 3]

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

import dis
dis.dis(func)

输出

  4           0 LOAD_FAST                0 (b)
              3 LOAD_FAST                1 (a)
              6 ROT_TWO             
              7 STORE_FAST               1 (a)
             10 STORE_FAST               0 (b)
             13 LOAD_CONST               0 (None)
             16 RETURN_VALUE

因此,Python使用. _ 所以,现在最上面的元素是由 指向的引用,下一个是由 指向的引用。然后它用于交换堆栈的顶部两个元素。因此,现在,最顶部的元素是 指向的引用,下一个是指向的引用,然后将堆栈的顶部两个元素分别分配给和。baLOAD_FASTabROT_TWObaabSTORE_FAST

当我们处理的项目数少于 4 时,这就是赋值语句中的排序方式。

如果项目的数量大于或等于四个,它会构建一个元组并解包这些值。检查这个程序

a, b, c, d = [1, 2], [2, 3], [4, 5], [5, 6]

def func():
    a, b, c, d  = d, c, b, a

import dis
dis.dis(func)

输出

  4           0 LOAD_FAST                0 (d)
              3 LOAD_FAST                1 (c)
              6 LOAD_FAST                2 (b)
              9 LOAD_FAST                3 (a)
             12 BUILD_TUPLE              4
             15 UNPACK_SEQUENCE          4
             18 STORE_FAST               3 (a)
             21 STORE_FAST               2 (b)
             24 STORE_FAST               1 (c)
             27 STORE_FAST               0 (d)
             30 LOAD_CONST               0 (None)
             33 RETURN_VALUE
于 2013-12-14T11:59:01.297 回答
2

因为 Python 赋值首先计算右侧的表达式,然后将结果应用于左侧的目标。

因此,首先,Python 创建(<reference to list b>, <reference to list a>)一个元组,然后将该元组中的第一项分配给 ,将该元组中a的第二项分配给b。这巧妙地交换了引用。

您可以将作业扩展为如下所示:

tmp = b, a
a = tmp[0]
b = tmp[1]
于 2013-12-14T11:59:06.920 回答
0

现在,它们如何像任何其他数据类型一样被交换并且最终不会都指向同一个列表?

因为当您将元组解压缩到元b, a组中时,a, b您就会失去对原始的引用,a并且b它们会被重新分配。

于 2013-12-14T12:00:25.637 回答