index()
只会在列表中首次出现一个项目。是否有一个巧妙的技巧可以返回列表中的所有索引?
答案 0 :(得分:405)
您可以使用列表理解:
indices = [i for i, x in enumerate(my_list) if x == "whatever"]
答案 1 :(得分:94)
虽然不是直接列表的解决方案,但numpy
确实对这类事情很感兴趣:
import numpy as np
values = np.array([1,2,3,1,2,4,5,6,3,2,1])
searchval = 3
ii = np.where(values == searchval)[0]
返回:
ii ==>array([2, 8])
对于具有大量元素的列表(数组)与其他一些解决方案相比,这可能会明显加快。
答案 2 :(得分:28)
使用list.index
的解决方案:
def indices(lst, element):
result = []
offset = -1
while True:
try:
offset = lst.index(element, offset+1)
except ValueError:
return result
result.append(offset)
对于大型列表,它比使用enumerate
的列表理解要快得多。如果你已经拥有数组,它也比numpy
解决方案慢得多,否则转换成本会超过速度增益(在100,1000和10000元素的整数列表上测试)。
注意:基于Chris_Rands评论的注意事项:如果结果足够稀疏,此解决方案比列表解析更快,但如果列表中有许多元素实例搜索(超过列表的约15%,在具有1000个整数的列表的测试中),列表理解更快。
答案 3 :(得分:16)
怎么样:
In [1]: l=[1,2,3,4,3,2,5,6,7]
In [2]: [i for i,val in enumerate(l) if val==3]
Out[2]: [2, 4]
答案 4 :(得分:7)
occurrences = lambda s, lst: (i for i,e in enumerate(lst) if e == s)
list(occurrences(1, [1,2,3,1])) # = [0, 3]
答案 5 :(得分:5)
more_itertools.locate
查找满足条件的所有项目的索引。
from more_itertools import locate
list(locate([0, 1, 1, 0, 1, 0, 0]))
# [1, 2, 4]
list(locate(['a', 'b', 'c', 'b'], lambda x: x == 'b'))
# [1, 3]
more_itertools
是第三方库> pip install more_itertools
。
答案 6 :(得分:4)
所有事件的另一个解决方案(对不起,如果重复):
values = [1,2,3,1,2,4,5,6,3,2,1]
map(lambda val: (val, [i for i in xrange(len(values)) if values[i] == val]), values)
答案 7 :(得分:3)
在python2中使用filter()。
>>> q = ['Yeehaw', 'Yeehaw', 'Googol', 'B9', 'Googol', 'NSM', 'B9', 'NSM', 'Dont Ask', 'Googol']
>>> filter(lambda i: q[i]=="Googol", range(len(q)))
[2, 4, 9]
答案 8 :(得分:2)
您可以创建一个defaultdict
from collections import defaultdict
d1 = defaultdict(int) # defaults to 0 values for keys
unq = set(lst1) # lst1 = [1, 2, 2, 3, 4, 1, 2, 7]
for each in unq:
d1[each] = lst1.count(each)
else:
print(d1)
答案 9 :(得分:2)
或使用range
(python 3):
l=[i for i in range(len(lst)) if lst[i]=='something...']
对于(python 2):
l=[i for i in xrange(len(lst)) if lst[i]=='something...']
然后(两种情况):
print(l)
符合预期。
答案 10 :(得分:1)
如果您需要在某些指数之间搜索所有元素的位置,您可以说明:
[i for i,x in enumerate([1,2,3,2]) if x==2 & 2<= i <=3] # -> [3]
答案 11 :(得分:1)
如果您使用的是Python 2,则可以使用它实现相同的功能:
f = lambda my_list, value:filter(lambda x: my_list[x] == value, range(len(my_list)))
其中my_list
是您要获取索引的列表,value
是搜索的值。用法:
f(some_list, some_element)
答案 12 :(得分:1)
使用enumerate(alist)可以存储第一个元素(n),当元素x等于您要查找的内容时,它就是列表的索引。
>>> alist = ['foo', 'spam', 'egg', 'foo']
>>> foo_indexes = [n for n,x in enumerate(alist) if x=='foo']
>>> foo_indexes
[0, 3]
>>>
此函数将项目和列表作为参数,并返回项目在列表中的位置,就像我们之前看到的那样。
def indexlist(item2find, list_or_string):
"Returns all indexes of an item in a list or a string"
return [n for n,item in enumerate(list_or_string) if item==item2find]
print(indexlist("1", "010101010"))
输出
[1, 3, 5, 7]
for n, i in enumerate([1, 2, 3, 4, 1]):
if i == 1:
print(n)
输出:
0
4
答案 13 :(得分:1)
np.where
查找单个值的索引np.where
和np.unique
查找列表中所有唯一元素的索引。list
转换为array
并使用np.where
比查找任何单个元素的所有索引的列表理解要快6.8x
。numpy
的快速解决方案import numpy as np
import random # to create test list
# create sample list
random.seed(365)
l = [random.choice(['s1', 's2', 's3', 's4']) for _ in range(20)]
# convert the list to an array for use with these numpy methods
a = np.array(l)
# create a dict of each unique entry and the associated indices
idx = {v: np.where(a == v)[0].tolist() for v in np.unique(a)}
# print(idx)
{'s1': [7, 9, 10, 11, 17],
's2': [1, 3, 6, 8, 14, 18, 19],
's3': [0, 2, 13, 16],
's4': [4, 5, 12, 15]}
# find a single element with
idx = np.where(a == 's1')
print(idx)
[out]:
(array([ 7, 9, 10, 11, 17], dtype=int64),)
%timeit
# create 2M element list
random.seed(365)
l = [random.choice(['s1', 's2', 's3', 's4']) for _ in range(2000000)]
# create array
a = np.array(l)
# np.where
%timeit np.where(a == 's1')
[out]:
25.9 ms ± 827 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
# list-comprehension
%timeit [i for i, x in enumerate(l) if x == "s1"]
[out]:
175 ms ± 2.73 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
答案 14 :(得分:1)
一个基于动态列表理解的解决方案,以防我们事先不知道哪个元素:
lst = ['to', 'be', 'or', 'not', 'to', 'be']
{req_word: [idx for idx, word in enumerate(lst) if word == req_word] for req_word in set(lst)}
结果:
{'be': [1, 5], 'or': [2], 'to': [0, 4], 'not': [3]}
您也可以按照相同的思路考虑所有其他方法,但是使用 index()
您只能找到一个索引,尽管您可以自己设置出现次数。
答案 15 :(得分:0)
for-loop
:enumerate
和list comprehension的答案更有效,更pythonic,但是,此答案针对的是可能不允许使用其中一些built-in functions的学生。indices
for i in range(len(x)):
创建循环,该循环实际上遍历索引位置[0, 1, 2, 3, ..., len(x)-1]
的列表i
与x[i]
匹配的value
添加到indices
def get_indices(x: list, value: int) -> list:
indices = list()
for i in range(len(x)):
if x[i] == value:
indices.append(i)
return indices
n = [1, 2, 3, -50, -60, 0, 6, 9, -60, -60]
print(get_indices(n, -60))
>>> [4, 8, 9]
get_indices
这些功能是通过type hints实现的。在这种情况下,列表n
是一堆int
,因此我们搜索value
,也定义为int
。while-loop
和.index
:.index
与try-except
一起使用,因为如果ValueError
不在列表中,则会出现value
。def get_indices(x: list, value: int) -> list:
indices = list()
i = 0
while True:
try:
# find an occurrence of value and update i to that index
i = x.index(value, i)
# add i to the list
indices.append(i)
# advance i by 1
i += 1
except ValueError as e:
break
return indices
print(get_indices(n, -60))
>>> [4, 8, 9]
答案 16 :(得分:0)
以下是使用np.where
与list_comprehension
之间的时间性能比较。似乎np.where
平均更快。
# np.where
start_times = []
end_times = []
for i in range(10000):
start = time.time()
start_times.append(start)
temp_list = np.array([1,2,3,3,5])
ixs = np.where(temp_list==3)[0].tolist()
end = time.time()
end_times.append(end)
print("Took on average {} seconds".format(
np.mean(end_times)-np.mean(start_times)))
Took on average 3.81469726562e-06 seconds
# list_comprehension
start_times = []
end_times = []
for i in range(10000):
start = time.time()
start_times.append(start)
temp_list = np.array([1,2,3,3,5])
ixs = [i for i in range(len(temp_list)) if temp_list[i]==3]
end = time.time()
end_times.append(end)
print("Took on average {} seconds".format(
np.mean(end_times)-np.mean(start_times)))
Took on average 4.05311584473e-06 seconds
答案 17 :(得分:-4)
编辑(白痴):
添加好的答案。
def count(x, lst):
ind = []
for i in lst:
if i == x:
ind.append(lst.index(x))
return ind