我是Python新手,刚刚学习了可变和不可变的对象。看来,当我们在列表中交换元素时,Python会创建各个元素的副本,然后将它们复制回列表中。
在上面的示例中,我们从n = [[1, 2], [3, 4]]
开始。第一个子列表[1, 2]
占用ID#24
,第二个子列表[3, 4]
占用ID#96
。起初,我认为由于列表是可变的,因此在交换后,ID#24
保持[3, 4]
而ID#96
保持[1, 2]
。但正如我们在上面的测试中所看到的那样,情况并非如此。相反,Python以我们的交换所确定的方式指向对象;列表的第一个插槽指向96
,第二个插槽指向24
。
当然,n
的ID#没有改变,因此n
没有违反可变对象的定义。但是这些子列表被交换的方式似乎是一个警告。你能用更精确的语言确认或解释吗?
答案 0 :(得分:3)
你错了ID。 ID#24是列表[1,2]
的ID。它不是n
中索引0的内存地址或ID。
您可能想尝试这样的示例来确认:
>>> x = [1, 2]
>>> id(x)
4332120256
>>> l = [x, 3]
>>> id(l[0])
4332120256
>>>
答案 1 :(得分:2)
将对象分配给目标列表按递归方式定义如下。
如果目标列表是单个目标:将对象分配给该目标。 如果目标列表是以逗号分隔的目标列表:对象必须是与目标列表中的目标具有相同数量的项目的可迭代项,并且项目从左到右分配到相应的目标。
如果你仔细阅读,你会发现你有这样的情景:
target_list = expression_list
表达式列表首先评估 ,并计算为元组:
赋值语句计算表达式列表(请记住,这可以是单个表达式或以逗号分隔的列表,后者产生元组)
所以如果你有:
a = [1, 2]
a[1], a[0] = a[0], a[1]
实际上就像编写以下内容一样:
a = [1, 2]
temp = (a[0], a[1]) # Expression list evaluates to tuple.
# target_list assignment to corresponding elements from expression list.
a[1] = temp[0]
a[0] = temp[1]