在Python中查找列表中匹配元素的索引
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16685384/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Finding the indices of matching elements in list in Python
提问by Logan Yang
I have a long list of float numbers ranging from 1 to 5, called "average", and I want to return the list of indices for elements that are smaller than a or larger than b
我有一长串从 1 到 5 的浮点数,称为“平均值”,我想返回小于 a 或大于 b 的元素的索引列表
def find(lst,a,b):
result = []
for x in lst:
if x<a or x>b:
i = lst.index(x)
result.append(i)
return result
matches = find(average,2,4)
But surprisingly, the output for "matches" has a lot of repetitions in it, e.g. [2, 2, 10, 2, 2, 2, 19, 2, 10, 2, 2, 42, 2, 2, 10, 2, 2, 2, 10, 2, 2, ...].
但令人惊讶的是,“匹配”的输出中有很多重复,例如[2, 2, 10, 2, 2, 2, 19, 2, 10, 2, 2, 42, 2, 2, 10, 2, 2, 2, 10, 2, 2, ...].
Why is this happening?
为什么会这样?
采纳答案by Martijn Pieters
You are using .index()which will only find the firstoccurrence of your value in the list. So if you have a value 1.0 at index 2, and at index 9, then .index(1.0)will alwaysreturn 2, no matter how many times 1.0occurs in the list.
您正在使用.index()which 只会在列表中找到您的值的第一次出现。因此,如果您在索引 2 和索引 9 处有一个值 1.0,那么无论列表中出现多少次,.index(1.0)都将始终返回。21.0
Use enumerate()to add indices to your loop instead:
用于enumerate()向循环添加索引:
def find(lst, a, b):
result = []
for i, x in enumerate(lst):
if x<a or x>b:
result.append(i)
return result
You can collapse this into a list comprehension:
您可以将其折叠为列表理解:
def find(lst, a, b):
return [i for i, x in enumerate(lst) if x<a or x>b]
回答by Sheng
>>> average = [1,3,2,1,1,0,24,23,7,2,727,2,7,68,7,83,2]
>>> matches = [i for i in range(0,len(average)) if average[i]<2 or average[i]>4]
>>> matches
[0, 3, 4, 5, 6, 7, 8, 10, 12, 13, 14, 15]
回答by Alex Coventry
It's a rather heavy dependency, but if you're doing a lot of this kind of thing you should consider using numpy.
这是一个相当严重的依赖,但如果你做了很多这样的事情,你应该考虑使用numpy.
In [56]: import random, numpy
In [57]: lst = numpy.array([random.uniform(0, 5) for _ in xrange(1000)]) # example list
In [58]: a, b = 1, 3
In [59]: numpy.flatnonzero((lst > a) & (lst < b))[:10]
Out[59]: array([ 0, 12, 13, 15, 18, 19, 23, 24, 26, 29])
In response to Seanny123's question, I used this timing code:
针对Seanny123的问题,我使用了这个时序代码:
import numpy, timeit, random
a, b = 1, 3
lst = numpy.array([random.uniform(0, 5) for _ in xrange(1000)])
def numpy_way():
numpy.flatnonzero((lst > 1) & (lst < 3))[:10]
def list_comprehension():
[e for e in lst if 1 < e < 3][:10]
print timeit.timeit(numpy_way)
print timeit.timeit(list_comprehension)
The numpy version is over 60 times faster.
numpy 版本快了 60 多倍。

