为什么我需要np.array()或np.copy()?

ner*_*com 6 python numpy

这是一个真正的numpy新手问题.

我有一个名为'image'的numpy数组.这样做:

image2 = image
image2[image < minval] = minval
image2[image > maxval] = maxval
Run Code Online (Sandbox Code Playgroud)

...更改"图片"的内容.

我收集的是因为Python中的变量确实是引用,所以'image2'只是引用'image'的另一种方式.所以我应该使用"image2 = np.copy(image)".精细.

但是,那么,当我这样做时,为什么不"改变":

a = 5
b = a
b = 7
Run Code Online (Sandbox Code Playgroud)

不是'b'只是提到'a'的另一种方式吗?如果是这样,为什么在这个结束时a == 7?

我想知道是否有一些心理模型使这看起来一致.因为它没有.

jez*_*jez 5

答案确实在于直接分配喜欢b=ab=7工作的方式。 b=a创建对也被引用的对象的新引用a,并将该新引用与名称关联b。然后,后续操作b=7删除附加到名称的引用,并与名称b建立不同的关联b。无论a是不可变类型(如整数)还是可变类型(如numpy数组),这都是正确的。两种情况都不会a被修改。

相比之下,image2[image < minval] = minval这不是重新分配。通过使用[]它,可以调用__setitem__对象的method()image2。此方法无需更改任何内容即可更改基础数据结构的某些部分image2

Python最基本的类型是“不可变的”。这意味着您无能为力,无法更改它们(例如,如果image2属于不可变类型tuple,则尝试使用[]索引更改其元素之一将引发异常)。

结果,非常非常宽松,如果您习惯了C / C ++的思维方式,有时在查看函数或函数时可以将不可变类型视为通过值传递而将可变类型视为通过引用传递方法原型。但是,正如注释中所指出的,这并不是真正发生的事情:所有内容都是引用,但是某些引用(不可变类型)将自动按照C / C ++处理const引用的方式进行处理。

不可变类型包括:

  • 基本数值类型:boolintlongfloatcomplex
  • 基本字符串类型:strunicode(仅限python 2.x)和bytes(仅限python 3.x)
  • tuple(但不是list

  • 这个答案极具误导性,因为它暗示了根据变量的可变性如何对待变量之间不存在区分。更糟糕的是,它使Python的行为看起来复杂而武断,而实际上却很简单:*不创建副本*。 (3认同)
  • 您可以在交互式解释器中对其进行测试。如果您执行a = 10000和b = 10000,则a is b将为False,因为Python恰巧制作了两个独立的int对象。但是,如果您执行“ b = a”,则“ a is b”将为“ True”。如果Python正在复制,则“ a”和“ b”将是单独的对象,而“ a是b”将是“ False”。 (2认同)