【发布时间】:2019-05-18 08:59:20
【问题描述】:
在 Raspberry Pi 上的 Raspbian 上使用 Spyder 3.1.3 中的 Python3.5.3。 将两个 numpy 数组附加到名为 'list0' 的列表中可以很好地与分配的 numpy 数组 'a' 类似:
import numpy as np
list0 = []
a = np.array([[1,2,3],[2,3,4]])
list0.append(a)
a = np.array([[11,12,13],[12,13,14]])
list0.append(a)
print("list0 =",list0)
效果很好,作为输出提供(帖子的格式更好):
list0 = [ array([[ 1, 2, 3], [ 2, 3, 4]]),
array([[11, 12, 13], [12, 13, 14]]) ]
使用循环将赋值替换为a,奇怪的事情发生了:
import numpy as np
a = np.empty((3), int)
list0 = []
for idx in range(4):
for i in range(3):
a[i] = idx*10 + i
print("idx =",idx,"; a =",a)
list0.append(a)
print("list0 =",list0)
第二行告诉 Python 使用的数组的形状(在我原来的例子中,它是一个三维数组)。为了验证生成的名为“a”的数组被打印出来。将新填充的数组 'a' 附加到 'list0' 最终显示最后一行的四倍。
idx = 0 ; a = [ 0 1 2]
idx = 1 ; a = [10 11 12]
idx = 2 ; a = [20 21 22]
idx = 3 ; a = [30 31 32]
list0 = [ array([30, 31, 32]), array([30, 31, 32]),
array([30, 31, 32]), array([30, 31, 32]) ]
我认为“list0”只包含四倍的指向数组“a”的指针,该数组仅存在于一个实例/内存范围中。
那么:如何将每个不同的数组 'a' 物理附加(复制?)到列表中?它是一个 python 错误还是只是我对某些东西的误解?当然,我应该多想pythonian ;c)
谢谢你的帮助,彼得
【问题讨论】:
-
这是将可变对象添加到列表时的常见问题。该列表存储指向对象的指针,在这种情况下,每个循环中的指针都是相同的。
a每次迭代都需要是一个新数组。您可以使用a = idx*10 + np.arange(3)保存迭代。 -
这是对 Python 语义的根本误解。阅读以下内容:nedbatchelder.com/text/names.html 在一种情况下,您正在创建两个不同的数组,并将它们附加到您的列表中,在另一种情况下,您创建一个数组,并将其两次附加到您的列表中,因此您的列表包含两个引用同一个数组。您可以使用
.copy方法复制数组。 -
@hpaulj 我认为最好不要考虑 Python 中的指针之类的东西(Python 中不存在),而是按照自己的术语学习语言。是的,确实如此,CPython 实现使用了一些原始的 PyObject 指针数组,但这是一个实现细节
-
@juanpa.arrivillaga,在 numpy 对象 dtype 数组的上下文中,我认为指针或引用是最好的术语。与
ndarray一样,数组的数据缓冲区存储itemsize元素,无论它们引用(或指向)什么。该术语延续到我对lists的讨论中。 -
没错,但列表不是指针列表。指针实际上与 python 无关。
标签: python arrays list numpy append