我们都知道,交换ab两项值的Python方法是

a, b = b, a

它应该相当于

b, a = a, b

然而,今天当我在编写一些代码时,我意外地发现以下两种交换给出了不同的结果:

nums = [1, 2, 4, 3]
i = 2
nums[i], nums[nums[i]-1] = nums[nums[i]-1], nums[i]
print(nums)
# [1, 2, 4, 3]

nums = [1, 2, 4, 3]
i = 2
nums[nums[i]-1], nums[i] = nums[i], nums[nums[i]-1]
print(nums)
# [1, 2, 3, 4]

这让我难以置信.有人能解释一下这里发生了什么吗?我认为在Python交换中,这两个任务同时独立地发生.

推荐答案

python.org

将对象分配到目标列表(可选地用括号或方括号括起来)的递归定义如下.

...

  • Else:对象必须是一个iterable,其项数必须与目标列表中的目标数相同,并且这些项从左到右分配给相应的目标.

所以我认为这意味着你的任务

nums[i], nums[nums[i]-1] = nums[nums[i]-1], nums[i]

大致相当于

tmp = nums[nums[i]-1], nums[i]
nums[i] = tmp[0]
nums[nums[i] - 1] = tmp[1]

(当然,还有更好的错误判断)

而另一个

nums[nums[i]-1], nums[i] = nums[i], nums[nums[i]-1]

就像

tmp = nums[i], nums[nums[i]-1]
nums[nums[i] - 1] = tmp[0]
nums[i] = tmp[1]

因此,在这两种情况下,首先判断右侧.然后按顺序对左手边的两个部分进行判断,判断后立即完成作业(job).至关重要的是,这意味着左手边的第二项只有在完成第一项任务后才能进行判断.因此,如果你先更新nums[i],那么nums[nums[i] - 1]所指的索引与更新nums[i]秒的索引不同.

Python-3.x相关问答推荐

合并两个数据帧并对某些总和进行求和

如何使用Selenium从网站下拉菜单中获取值列表?

在Python中基于组/ID将两个数据帧进行映射,找出较接近的值

ImportError:抓取数据后找不到 html5lib

将自动文本转换为 DataFrame

如何统计一个值连续出现的次数?

Pytest顺序测试A,然后测试B,然后再测试A

如何将 OLS 趋势线添加到使用 updatemenus 显示数据子集的 plotly 散点图图形对象?

!date 的命令无法从 jupyter notebook 运行

为列表列表中的每个列表插入 str 到 index[0] 中. Python

机器学习实验笔记本的工作区 url

python3:字节与字节数组,并转换为字符串和从字符串转换

如何从左到右解包元组?

在带有 M1 芯片(基于 ARM 的 Apple Silicon)的 Mac 上安装较早版本的 Python(3.8 之前)失败

使用 Sublime Text 3 在 Python 3 中打印 UTF-8

如何在元素列表中找到最大的数字,可能是非唯一的?

所有 Python dunder 方法的列表 - 您需要实现哪些方法才能正确代理对象?

使用 Python3 与 HDFS 交互的最佳模块是什么?

如何使用 asyncio 添加连接超时?

使用 python2 和 python3 创建一个 virtualenv