I'd like to slice a numpy array to get all but the first item, unless there's only one element, in which case, I only want to select that element (i.e. don't slice).
Is there a way to do this without using an if-statement?
x = np.array([1,2,3,4,5])
y = np.array([1])
print(x[1:]) # works
print(y[1 or None:]) # doesn't work
I tried the above, but it didn't work.
CodePudding user response:
A way to write that without a conditional is to use negative indexing with -len(arr) 1
:
>>> x = np.array([1,2,3,4,5])
>>> y = np.array([1])
>>> x[-len(x) 1:]
array([2, 3, 4, 5])
>>> y[-len(y) 1:]
array([1])
If the array has N elements where N > 1, slice becomes -N 1:
. Since -N 1 < 0, it is effectively (N (-N 1)): === 1:
, i.e, first one onwards.
Elsewhen N == 1, slice is 0:
, i.e., take the first element onwards which is the only element.
Because of how slicing works, an empty array (i.e., N = 0 case) will result in an empty array too.
CodePudding user response:
You can just write an if / else:
x[1 if len(x) > 1 else 0:]
array([2, 3, 4, 5])
y[1 if len(y) > 1 else 0:]
array([1])
Or:
y[int(len(y) > 1):]
array([1])
x[int(len(x) > 1):]
array([2, 3, 4, 5])
CodePudding user response:
Just move None out of the brackets
x = [1,2,3,4,5]
y = [1]
print(x[1:])
print(y[1:] or None)
CodePudding user response:
Check the array size is greater than 1 if the case you can delete the first element from array and it will give new array without it.
print(np.delete(x, 0))
Now your can get a new array which will contain only remaining items other than first.
CodePudding user response:
Use a ternary expression to make the logic clear but still be able to use it as a function argument or inside other expressions.
The ternary expression x[0] if len(x) == 1 else x[1:]
works and is very clear. And you can use it as a parameter in a function call, or in a larger expression.
E.g.:
>>> x = np.array([1,2,3,4,5])
>>> y = np.array([1])
>>> print(x[0] if len(x) == 1 else x[1:])
[2 3 4 5]
>>> print(y[0] if len(y) == 1 else y[1:])
[]
Musings on other solutions
I'm not sure if you're looking for the most concise code possible to do this, or just for the ability to have the logic inside a single expression.
I don't recommend fancy slicing solutions with negative indexing, for the sake of legibility of your code. Think about future readers of your code, even yourself in a year or two.