有时候,会有这种小需求,但是又不想遍历一遍list(太蠢了,写出这种代码,都不好意思把代码给别人看了😹),因此我们需要一种简单便捷,看起来像这么回事的一行代码来解决问题。



Python获取列表list中的非零数据、第一个非零元素、最后一个非零元素_list


废话不多说,直接上代码。

import numpy as np

list = [[1, 0, 0], [0, 5, 0], [0, 0, 9]]
list = np.array(list)
print(list.ravel()[np.flatnonzero(list)].tolist())
# 执行结果
[1, 5, 9]


想要深入理解的继续向下看。首先看下numpy提供的两个函数:

import numpy as np

list = [[1, 0, 0],
[0, 5, 0],
[0, 0, 9]]
print(np.nonzero(list))
print(np.flatnonzero(list))

# 执行结果
(array([0, 1, 2]), array([0, 1, 2]))
[0 4 8]

​ 可以看到nonzero()函数会将多维数组中的非零元素的索引进行返回,并且返回结果的纬度和数组的纬度相同。flatnonzero()函数是将多维数组按照​​行优先排列​​的方式转成一维数组并返回其中非零元素的索引

下面我们在来看一个函数:

list = np.array([[1, 0, 0],
[0, 5, 0],
[0, 0, 9]])
print(list.ravel())

# 执行结果
[1 0 0 0 5 0 0 0 9]

ravel()函数是numpy提供的,其功能为将一个多维数组以行优排列转为一维数组。

哦,是不是很类似,我们可以将ravel()、flatnonzero()两个函数相结合,来实现我们的需求。代码如下:

import numpy as np

list = [[1, 0, 0],
[0, 5, 0],
[0, 0, 9]]
list = np.array(list)
print(list.ravel()[np.flatnonzero(list)])
print(list.ravel()[np.flatnonzero(list)].tolist())


# 执行结果
[1 5 9]
[1, 5, 9]

最后,我们将ravel()、flatnonzero()两个函数结合取得的结果转成list,就得到了我们想要的结果。

美中不足的是,ravel()函数是mumpy提供的函数,需要先将list转为array。并且即使list本身是一维数组,不需要转换成一维数组,但是list本身是无法直接获取多个非连续索引的值,因此只能借助array了。

因此如果你想获取第一个、最后一个、或者指定顺序的单个非零元素的话,可以无需转成array,代码如下:

list = [0, 1, 0, 0, 3, 0, 0, 5]

# 获取第一个非0元素
print(list[np.flatnonzero(list2)[0]])
# 获取倒数第一个非0元素
print(list[np.flatnonzero(list2)[-1]])

当然这种用法要注意数组越界问题,需提前验证list中存在非零元素。