[英]Getting the indices of all non-None items from a sub-list in Python?
As per the title, I have a nested lists like so (the nested list is a fixed length): 按照标题,我有一个像这样的嵌套列表(嵌套列表是固定长度的):
# ID, Name, Value
list1 = [[ 1, "foo", 10],
[ 2, "bar", None],
[ 3, "fizz", 57],
[ 4, "buzz", None]]
I'd like to return a list (the number of items equal to the length of a sub-list from list1
), where the sub-lists are the indices of rows without None as their Xth item, ie: 我想返回一个列表(项的数量等于
list1
的子列表的长度),其中子列表是不带None作为第X项的行的索引,即:
[[non-None ID indices], [non-None Name indices], [non-None Value indices]]
Using list1
as an example, the result should be: 以
list1
为例,结果应为:
[[0, 1, 2, 3], [0, 1, 2, 3], [0, 2]]
My current implementation is: 我目前的实施是:
indices = [[] for _ in range(len(list1[0]))]
for i, row in enumerate(list1):
for j in range(len(row)):
if not isinstance(row[j], types.NoneType):
indices[j].append(i)
...which works, but can be slow (the lengths of the lists are in the hundreds of thousands). ...这是可行的,但可能会很慢(列表的长度成千上万)。
Is there a better/more efficient way to do this? 有没有更好/更有效的方法来做到这一点?
EDIT: 编辑:
I've refactored the above for loops into nested list comprehensions (similar to SilentGhost's answer). 我已经将上述for循环重构为嵌套列表推导(类似于SilentGhost的答案)。 The following line gives the same result as the my original implementation, but runs approximately 10x faster.
以下行给出的结果与我的原始实现相同,但运行速度提高了约10倍。
[[i for i in range(len(list1)) if list1[i][j] is not None] for j in range(len(log[0]))]
>>> [[i for i, j in enumerate(c) if j is not None] for c in zip(*list1)]
[[0, 1, 2, 3], [0, 1, 2, 3], [0, 2]]
in python-2.x you could use itertools.izip
instead of zip
to avoid generating intermediate list. 在python-2.x中,可以使用
itertools.izip
而不是zip
来避免生成中间列表。
[[i for i in range(len(list1)) if list1[i] is not None] for _ in range(len(log[0]))]
上面的内容似乎比我的原始帖子快10倍。
import numpy as np
map(lambda a: np.not_equal(a, None).nonzero()[0], np.transpose(list1))
# -> [array([0, 1, 2, 3]), array([0, 1, 2, 3]), array([0, 2])]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.