简体   繁体   中英

Why do I need np.array() or np.copy()?

A real numpy newbie question here.

I have an numpy array called 'image'. Doing this:

image2 = image
image2[image < minval] = minval
image2[image > maxval] = maxval

...changes the contents of 'image'.

I gather that's because variables in Python are really references, so 'image2' is just another way of referring to 'image'. So I'm supposed to use "image2 = np.copy(image)". Fine.

But, then, why doesn't 'a' change when I do this:

a = 5
b = a
b = 7

Isn't 'b' just another way of referring to 'a'? If so, why doesn't a==7 at the end of this?

I want to know if there's some mental model that makes this seem consistent. Because it doesn't.

The answer really lies in the way direct assignments like b=a and b=7 work. b=a creates a new reference to the object also referenced by a , and associates that new reference with the name b . The subsequent b=7 then removes the reference that was attached to the name b , and makes a different association with the name b . This will be true whether a is an immutable type (like an integer) or a mutable type (like a numpy array). In neither case will the content of a be modified.

By contrast, image2[image < minval] = minval is not a reassignment. Via its use of [] it calls a method ( __setitem__ ) of the object image2 . This method changes parts of the underlying data structure without reassigning anything to image2 .

Python's most fundamental types are "immutable". This means that nothing you can do will change them (for example, if image2 were of the immutable type tuple , trying to change one of its elements with [] indexing would cause an exception to be raised).

As a result, very very loosely , if you're accustomed to a C/C++ mindset, it can sometimes help to think of immutable types as being passed by value and mutable types being passed by reference when you're looking at a function or method prototype. As pointed out in the comments, though, this is not really what happens: everything is a reference, but some references (the immutable types) are automatically treated the way C/C++ would treat const references.

The immutable types include:

  • basic numeric types: bool , int , long , float and complex
  • basic string types: str , unicode (python 2.x only) and bytes (python 3.x only)
  • tuple (but not list )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM