切片除第一个元素外的所有元素,除非是单个元素
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
,所以我相应地更新了我的答案。
我想对 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
,所以我相应地更新了我的答案。