如何将过滤器功能应用于多个列表中的项目?

时间:2019-05-20 09:39:59

标签: python list-comprehension

我想从多(?)列表中获取值,不为0 (我认为filter可能是解决方案之一)。

列表如下:

>>ls = [[i for i in np.random.randint(0, 5, 5)] for _ in range(7)]
>>ls
>>
[[2, 3, 3, 0, 0],
 [4, 2, 4, 3, 2],
 [1, 2, 4, 2, 4],
 [2, 3, 4, 3, 1],
 [0, 1, 0, 3, 0],
 [3, 4, 4, 4, 3],
 [3, 4, 3, 3, 2]]

预期结果为:

[2,3,3,4,2,4,3,2,1,2,4,2,4,2,3,4,3,1,1,3,3,4,4,4,3,3,4,3,3,2]

我尝试使用 filter函数,想扩展这个想法,但失败了:

>> [elem for elem in filter(lambda x: x if x != 0 else False, ls[0])]
>> 
[2, 3, 3]

我想找到最快的方法来获得预期的结果,而不使用for loop。 你有什么好主意吗?

编辑:

糟糕,对不起,您感到困惑。 我说的是“不为循环使用”,我想使用列表理解而不是for loop,因为我听说列表理解比for loop更为重要。

2 个答案:

答案 0 :(得分:3)

使用嵌套列表理解:

[j for i in ls for j in i if j != 0]

ls = [[i for i in np.random.randint(0, 5, 5)] for _ in range(7)]

[[1, 0, 3, 0, 0],
 [1, 2, 2, 3, 0],
 [1, 1, 1, 4, 3],
 [1, 0, 3, 0, 4],
 [2, 0, 3, 0, 2],
 [1, 0, 4, 4, 0],
 [2, 4, 1, 1, 2]]

[j for i in ls for j in i if j != 0]
# [1, 3, 1, 2, 2, 3, 1, 1, 1, 4, 3, 1, 3, 4, 2, 3, 2, 1, 4, 4, 2, 4, 1, 1, 2]

如果您想避免任何显式循环,则可以使用itertools.chainfilter

from itertools import chain

list(filter(lambda x: x != 0, chain(*ls)))
# [1, 3, 1, 2, 2, 3, 1, 1, 1, 4, 3, 1, 3, 4, 2, 3, 2, 1, 4, 4, 2, 4, 1, 1, 2]

好像您也使用NumPy创建列表。请注意,使用np.nonzero可以更简单,更高效:

import numpy as np
a = np.random.randint(0, 5, (7,5))
a[np.nonzero(a)]
# [1, 3, 1, 2, 2, 3, 1, 1, 1, 4, 3, 1, 3, 4, 2, 3, 2, 1, 4, 4, 2, 4, 1, 1, 2]

答案 1 :(得分:2)

添加到@yatu的答案中,因为它是0,所以您只需执行if x

print([x for i in ls for x in i if x])

或无循环:

print(np.array(ls).flatten()[np.array(ls).flatten() != 0].tolist())

两个输出:

[1, 4, 4, 2, 1, 3, 3, 4, 4, 1, 3, 3, 2, 2, 2, 1, 4, 2, 2, 1, 4, 1, 2, 3, 2, 4]