切片除第一个元素外的所有元素,除非是单个元素

Slice all except first element, unless single element

我想对 numpy 数组进行切片以获得除第一项以外的所有项,除非只有一个元素,在这种情况下,我只想 select 该元素(即不切片) .

有没有不使用 if 语句就可以做到这一点的方法?

x = np.array([1,2,3,4,5])
y = np.array([1])
print(x[1:]) # works
print(y[1 or None:]) # doesn't work 

上面的方法我都试过了,还是不行。

你可以只写一个 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])

或者:

y[int(len(y) > 1):]
array([1])

x[int(len(x) > 1):]
array([2, 3, 4, 5])

把None移出括号

x = [1,2,3,4,5]
y = [1]
print(x[1:]) 
print(y[1:] or None)

检查数组大小是否大于 1,如果可以从数组中删除第一个元素,它会给出没有它的新数组。

打印(np.delete(x, 0))

现在您可以获得一个新数组,它只包含除第一个以外的剩余项。

一种没有条件的写法是使用负索引 -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])

如果数组有 N 个元素,其中 N > 1,切片变为 -N+1:。由于 -N+1 < 0,它实际上是 (N + (-N + 1)): === 1:,即第一个开始。

否则当 N == 1 时,切片是 0:,即从第一个元素开始,这是唯一的元素。

由于切片的工作原理,空数组(即 N = 0 的情况)也会导致空数组。

使用三元表达式使逻辑清晰,但仍然可以将其用作函数参数或在其他表达式中使用。

三元表达式x if len(x) == 1 else x[1:]有效并且非常清晰。并且您可以将它用作函数调用中的参数,或者在更大的表达式中。

例如:

>>> x = np.array([1,2,3,4,5])
>>> y = np.array([1])
>>> print(x if len(x) == 1 else x[1:])
[2 3 4 5]
>>> print(y if len(y) == 1 else y[1:])
[1]

对其他解决方案的思考

我不确定您是在寻找最简洁的代码来执行此操作,还是只是为了能够在单个表达式中包含逻辑。

为了代码的易读性,我不推荐带有负索引的花式切片解决方案。想想你代码的未来读者,甚至是一两年后你自己。

使用这个是一个更大的表达式

在评论中,您提到您需要一个可以纳入理解之类的解决方案。三元表达式可以在理解范围内按原样使用。例如,此代码有效:

l = [np.array(range(i)) for i in range(5)]
l2 = [
    x if len(x) == 1 else x[1:]
    for x in l
]

我添加了间距以使代码更易于阅读,但它也可以作为单行代码使用:

l2 = [x if len(x) == 1 else x[1:] for x in l]

编辑注释

早些时候,我认为您希望在单元素情况下从列表中提取第一个元素,即 x[0],但我相信您实际上希望该单元素列表未切片,即 x,所以我相应地更新了我的答案。