【问题标题】:Understanding python arrays了解python数组
【发布时间】:2017-02-16 12:52:57
【问题描述】:

我无法理解数组在 python 中的工作原理。

我编写了这个简短的演示代码:

from numpy import zeros

a = zeros((3), 'd')
b = zeros((2,3), 'd')
for i in range(2):
    for j in range(3):
        a[j] = i*j
    b[i] = a
print "A: " + str(a) + "\n"
print "B: " + str(b)

这个输出是:

A: [ 0.  1.  2.]
B: [[ 0.  0.  0.] [ 0.  1.  2.]]

所以这是我的问题。为什么不是这个输出:

A: [ 0.  1.  2.]
B: [[ 0.  1.  2.] [ 0.  1.  2.]]

因为我在同一个a中进行了更改,并且数组的地址没有改变。

【问题讨论】:

  • 因为您将所有b 子列表的引用更改为a
  • for i in range(2) -> 你的第一个循环特征值i=0,设置a[j] = 0 为所有j -> b[0] = [0. 0. 0.]
  • 是的,但它是同一个地址。 b 的所有子列表都指向同一个地址。所以最后这些值应该是我在数组中写入的最后一个值吗?
  • b[0] 不是子列表 - 它是数组中的一行。
  • 我认为问题是,为什么b[0,:] 不是viewa?为什么要复制? b[1,:] 是视图还是副本?列表会发生什么

标签: python arrays numpy memory


【解决方案1】:

你似乎在假设

b[i] = a

将对a 的引用插入b。事实并非如此。分配给数组切片会复制数据。这种行为类似于使用列表进行切片分配。

也许混淆来自于它反过来不同?

a = b[i]

不复制,它创建一个视图;这与列表切片不同。

【讨论】:

  • 啊。好的,我认为它就像在 Java 或 C++ 中一样,它只是一个参考。谢谢!
【解决方案2】:

它的 [0. 0. 0.] 因为:

第一个循环以“0”开头 所以你有“i”的零:

a[j] = 0*j

所有乘以 0 都是零。

【讨论】:

  • 是的,这很清楚。我的问题如下。在第二次迭代中,我将值 [0,1,2] 写入数组 a。现在假设a的地址是0x2A。所以 b[0] 指向地址 0x2A,而 b[1] 也指向地址 0x2A。 0x2A 是数组 a,我为 a 创建的最后一个条目是 [0,1,2]。所以 b 的内容应该是 [[0,1,2],[0,1,2]]
【解决方案3】:

数组不会表现出您期望的行为,但列表会。请参阅以下示例:

import numpy as np

a = np.zeros(3, 'd')
b = np.zeros(3, 'd')
c = np.zeros((2,3), 'd')

c[0] = a
c[1] = b

a[1] = 2
b[0] = 1

print 'Matrix A: {}'.format(a)
print 'Matrix B: {}'.format(b)
print 'Matrix C: {}'.format(c)

a = [0, 0, 0]
b = [0, 0, 0]
c = [a, b]

a[1] = 2
b[0] = 1

print 'List A: {}'.format(a)
print 'List B: {}'.format(b)
print 'List C: {}'.format(c)

当我们使用矩阵时,c[0] 复制a 的当前值,c[1]b 执行相同的操作。引用丢失,因此对ab 的修改对c 没有影响。因此,我们打印:

Matrix A: [ 0.  2.  0.]
Matrix B: [ 1.  0.  0.]
Matrix C: [[ 0.  0.  0.]
 [ 0.  0.  0.]]

但是对于列表,引用会被保留。因此,我们打印:

List A: [0, 2, 0]
List B: [1, 0, 0]
List C: [[0, 2, 0], [1, 0, 0]]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-23
    • 2012-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多