The decision by python and apparently numpy to not return an object after its mutation is a source of frequent inconvenience. This question will be based on a different approach: to use a builder pattern so that we can do this:
x = np.random.randint(0,10+1,50).sort()[:5]
and end up with the least five values from a random set of ten numbers. Instead the above results in a runtime error due to subscripting None after the sort. I am wondering if there were either a library that provides that builder pattern atop numpy or some way to coerce all mutation numpy methods to return self instead of None.
For a single mutation the numpy method might suffice:
x = np.sort(np.random.randint(0,10+1,50))[:5]
But that approach does not scale when a series of methods are required. E.g.
x = np.resize(np.sort(np.random.randint(0,10+1,50))[:5],[5,1])
That quickly becomes difficult not only to write but also to read: we are asked to both write and read the code "inside out" from right to left.
Update A "winner" was declared below. Making a slight modification - renaming from ChainWrapper to Wrp just for brevity - here is the usage on both a list and an (numpy) ndarray:
Wrp(list(range(0,10,2))).append(8).append(10).insert(0, "hello").reverse().unwrap()[0:2]
# list:[10, 8]
import numpy as np
Wrp(np.linspace(0, 9, 10)).reshape(5, 2)[1:3, 0])
# np.array: array([2., 4.])
The point is : append, insert reverse and reshape return None . The Wrp detects that and returns self instead. Frequently I want to write a lambda that performs more than one operation on a list. It was not possible to do so without the above.