我想从多(?)列表中获取值,不为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
更为重要。
答案 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.chain
和filter
:
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]