Numpy 数组和列表的多重赋值,一个奇怪的例子

Posted

技术标签:

【中文标题】Numpy 数组和列表的多重赋值,一个奇怪的例子【英文标题】:Multiple assignment with Numpy arrays and lists, a curious example 【发布时间】:2017-04-30 20:15:25 【问题描述】:

考虑多重赋值x[0],y = y,x[0]。应用到以下四种情况中的每一种,这会产生四种不同的结果。

案例一:

x = [[1,2], [3,4]]
y = [5,6]

给予

x = [[5,6], [3,4]]
y = [1,2]

案例 2:

x = np.array([[1,2], [3,4]])
y = [5,6]

给予

x = array([[5,6], [3,4]])
y = array([5,6])

案例 3:

x = [[1,2], [3,4]]
y = np.array([5,6])

给予

x = [array([5,6]), [3,4]]
y = [1,2]

案例 4:

x = np.array([[1,2], [3,4]])
y = np.array([5,6])

给予

x = array([[5,6], [3,4]])
y = array([5,6])

列表的多重赋值似乎比 Numpy 数组的多重赋值更智能(自动通过临时变量)。

想法?

编辑:毕竟不是更聪明...

【问题讨论】:

“看起来列表的多重赋值比 Numpy 数组的多重赋值更智能(自动通过一个临时变量)。” - 为何如此?当分配给 Numpy 数组时,它会将其变成 Numpy 数组的一部分。 【参考方案1】:

这里唯一令人惊讶的情况应该是 2 和 4:

x = np.array([[1,2], [3,4]])
y = np.array([5,6])  # or [5, 6]

给予

x = array([[5,6], [3,4]])
y = array([5,6])  # where did the 1 and 2 go?

因为其他只是交换数据类型,但保持相同的值。

使用 numpy 时的不同之处在于 x[0] 返回的是视图,而不是副本。因此,即使在元组赋值中明确写出临时值也会失败:

temp = x[0]
x[0] = y
y = temp

因为temp 是一个始终与x[0] 相同的视图,而不是当时x[0] 值的副本。

要使这项工作适用于 numpy 案例,您应该使用 x[0],y = y,x[0].copy()

【讨论】:

嗯,是的,2 和 4 是有趣的,但为了完整起见,我将它们都添加了。【参考方案2】:
x[0],y = y,x[0]

等于

t = x[0]
x[0] = y
y = t

正如@Scimonster 指出的那样,

当分配给一个 Numpy 数组时,它会将它变成 numpy 数组。

所以这是正常行为。

【讨论】:

这两个代码块并不相等。未创建临时变量t;在内部,yx[0] 被压入堆栈,被翻转,然后被弹回以进行分配。这两种方法可能导致不同的结果。 @ajcr:除了名称t被破坏之外,你能构造一个结果不同的案例吗? @Eric:我想我记错了类似this question 的东西,我之前遇到过(我现在看到它不涉及临时变量)。我认为应该可以构建一些奇怪的例子,在赋值期间改变变量(所以保持一个临时变量不变),但在我能想出一些令人信服的东西之前,我会收回我之前的评论。

以上是关于Numpy 数组和列表的多重赋值,一个奇怪的例子的主要内容,如果未能解决你的问题,请参考以下文章

将一个 numpy 数组附加到一个列表 - 奇怪的事情

如何使用numpy数组的引用坐标处理奇怪的索引行为?

处理numpy数组时赋值运算符中的指针行为?

Numpy学习100例

Numpy:如何在 numpy 中选择项目并为其赋值

NumPy字符串速查表