繁体   English   中英

如何获取列表中非零元素的索引列表?

[英]How do I get a list of indices of non zero elements in a list?

我有一个始终只包含 1 和 0 的列表。 我需要获取列表的非零索引列表:

a = [0, 1, 0, 1, 0, 0, 0, 0]
b = []
for i in range(len(a)):
    if a[i] == 1:  b.append(i)
print b

实现这一目标的“pythonic”方式是什么?

[i for i, e in enumerate(a) if e != 0]

不是真正的“新”答案,但numpy也内置了这个。

import numpy as np
a = [0, 1, 0, 1, 0, 0, 0, 0]
nonzeroind = np.nonzero(a)[0] # the return is a little funny so I use the [0]
print nonzeroind
[1 3]

由于 THC4k 提到了压缩(在 python2.7+ 中可用)

>>> from itertools import compress, count
>>> x = [0, 1, 0, 1, 0, 0, 0, 0]
>>> compress(count(), x)
<itertools.compress object at 0x8c3666c>   
>>> list(_)
[1, 3]

只是想为上一个答案的“有趣”输出添加解释。 结果是一个元组,其中包含矩阵每个维度的索引向量。 在这种情况下,用户正在处理 numpy 中被视为向量的内容,因此输出是具有一个元素的元组。

import numpy as np
a = [0, 1, 0, 1, 0, 0, 0, 0]
nonzeroind = np.nonzero(a) 
print nonzeroind
(array([1, 3]),)

两个答案与列表长度的时间比较

a = [int(random.random()>0.5) for i in range(10)]
%timeit [i for i, e in enumerate(a) if e != 0]
683 ns ± 14 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
%timeit np.nonzero(a)[0]
4.43 µs ± 102 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

a = [int(random.random()>0.5) for i in range(1000)]
%timeit [i for i, e in enumerate(a) if e != 0]
53.1 µs ± 2.02 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
%timeit np.nonzero(a)[0]
73.8 µs ± 2.71 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

a = [int(random.random()>0.5) for i in range(100000)]
%timeit [i for i, e in enumerate(a) if e != 0]
5.86 ms ± 79.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit np.nonzero(a)[0]
6.61 ms ± 14.4 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

列表长度为 100000,改变列表中的数量

a = [int(random.random()>0.1) for i in range(100000)]
%timeit [i for i, e in enumerate(a) if e != 0]
6.45 ms ± 28.8 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit np.nonzero(a)[0]
5.74 ms ± 9.25 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

a = [int(random.random()>0.9) for i in range(100000)]
%timeit [i for i, e in enumerate(a) if e != 0]
4.69 ms ± 12.6 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit np.nonzero(a)[0]
5.74 ms ± 6.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

数量只影响第一个选项。 np.nonzero() 对于大量非零元素更好。 如果长度小于 10000,则第一个选项更快。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM