102

Is there a simple way to create an immutable NumPy array?

If one has to derive a class from ndarray to do this, what's the minimum set of methods that one has to override to achieve immutability?

2
  • Why do you need immutability? Commented Apr 4, 2011 at 16:20
  • 55
    @KennyTM To avoid coding errors caused by accidentally modifying something that's assumed invariant. Commented Apr 4, 2011 at 16:22

3 Answers 3

154

You can make a numpy array unwriteable:

a = np.arange(10)
a.flags.writeable = False
a[0] = 1
# Gives: ValueError: assignment destination is read-only

Also see the discussion in this thread:

http://mail.scipy.org/pipermail/numpy-discussion/2008-December/039274.html

and the documentation:

http://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.flags.html

Sign up to request clarification or add additional context in comments.

13 Comments

Alternatively, a.setflags(write=False).
@aix: A quick look at the documentation would make it seem as if the two approaches are identical. Personally, I prefer using a method to set attributes.
Does this also make it memoizable?
IMPORTANT!! Numpy DOES NOT have an immutable array. Arrays with .flags.writeable = False are still not immutable. If x is an array, y = x[:]; x.flags.writeable = False; y[0] = 5 updates the first element of x to 5.
@JamesParker It seems the flags come with the array when you slice. So if the writable flag is set to False before you slice then then y above would fail on update.
|
3

Setting the flag directly didn't work for me, but using ndarray.setflags did work:

a = np.arange(10)
a.setflags(write=False)
a[0] = 1  # ValueError

Comments

0

I have a subclass of Array at this gist: https://gist.github.com/sfaleron/9791418d7023a9985bb803170c5d93d8

It makes a copy of its argument and marks that as read-only, so you should only be able to shoot yourself in the foot if you are very deliberate about it. My immediate need was for it to be hashable, so I could use them in sets, so that works too. It isn't a lot of code, but about 70% of the lines are for testing, so I won't post it directly.

Note that it's not a drop-in replacement; it won't accept any keyword args like a normal Array constructor. Instances will behave like Arrays, though.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.