从Python的子列表中获取所有非None项的索引?

发布于 2024-09-01 02:23:34 字数 1029 浏览 3 评论 0原文

根据标题,我有一个像这样的嵌套列表(嵌套列表是固定长度):

        # ID,  Name, Value
list1 = [[ 1, "foo",    10],
         [ 2, "bar",  None],
         [ 3, "fizz",   57],
         [ 4, "buzz", None]]

我想返回一个列表(项目数等于 list1< 中的子列表的长度) /code>),其中子列表是没有 None 作为第 X 项的行的索引,即:

[[non-None ID indices], [non-None Name indices], [non-None Value indices]]

list1 为例,结果应该是:

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

我当前的实现是:

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)

...它有效,但可能很慢(列表的长度有数十万)。

有没有更好/更有效的方法来做到这一点?

编辑:

我已将上述 for 循环重构为嵌套列表理解(类似于 SilentGhost 的答案)。以下行给出的结果与我最初的实现相同,但运行速度大约快 10 倍。

[[i for i in range(len(list1)) if list1[i][j] is not None] for j in range(len(log[0]))]

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, i.e.:

[[non-None ID indices], [non-None Name indices], [non-None Value indices]]

Using list1 as an example, the result should be:

[[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). The following line gives the same result as the my original implementation, but runs approximately 10x faster.

[[i for i in range(len(list1)) if list1[i][j] is not None] for j in range(len(log[0]))]

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

北方的巷 2024-09-08 02:23:34
>>> [[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]]

在 python-2.x 中,您可以使用 itertools.izip 而不是 zip 来避免生成中间列表。

>>> [[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.

生活了然无味 2024-09-08 02:23:34
[[i for i in range(len(list1)) if list1[i] is not None] for _ in range(len(log[0]))]

上面的内容似乎比我原来的帖子快了大约 10 倍。

[[i for i in range(len(list1)) if list1[i] is not None] for _ in range(len(log[0]))]

The above seems to be about 10x faster than my original post.

等往事风中吹 2024-09-08 02:23:34
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])]
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])]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文