index()
只会给出列表中第一个出现的项目。有没有整齐的技巧可以返回列表中的所有索引?
index()
只会给出列表中第一个出现的项目。有没有整齐的技巧可以返回列表中的所有索引?
Answers:
您可以使用列表理解:
indices = [i for i, x in enumerate(my_list) if x == "whatever"]
enumerate
为2.3。是的,如果您的Python很古老,请使用filter()
。
print([i for i, x in enumerate([[1,1],[0,1]]) if x == 1])
返回[]
而不是[[0, 1], [0, 0], [1, 1]]
。
(a == 1).nonzero()
NumPy array的操作a
。
虽然不是直接解决列表问题的方法,但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])
与其他一些解决方案相比,这对于包含大量元素的列表(数组)而言可能会更快。
[0]
是必需的,因为会where
返回一个元组(array([2, 8], dtype=int64),)
all_id_resp_address
应该。np.array
list
list
和str
,很明显,你传递False
给np.where
。np.array
与smth 比较时。您将获得一个布尔值数组。然后np.where
找到True
该数组所有值的位置。
使用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个整数列表的测试中),列表理解速度更快。
timeit.timeit
了随机生成的列表。不过,这很重要,我想那可能就是你问的原因。当时我还没有想到,但是只有在结果足够稀疏的情况下,速度提升才是正确的。我只是用一个充满要搜索元素的列表进行了测试,它比列表理解要慢得多。
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
。
conda install
针对所有情况的另一种解决方案(对不起,如果重复的话):
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)
在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]
使用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
for-loop
:enumerate
和列表理解的答案更高效,更pythonic,但是,此答案针对的是可能不允许使用某些内置函数的学生。indices
for i in range(len(x)):
,从本质上遍历索引位置列表[0, 1, 2, 3, ..., len(x)-1]
i
,这里x[i]
是一个比赛value
,以indices
x[i]
按索引访问列表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
带有类型提示。在这种情况下,列表s n
是一堆int
,因此我们搜索value
,也定义为int
。while-loop
和.index
:.index
,try-except
用于错误处理,因为ValueError
如果value
不在列表中,则会出现a 。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]
get_indeices
速度比普通列表理解要快(〜15%)。我想弄清楚。
如果需要搜索某些索引之间所有元素的位置,则可以声明它们:
[i for i,x in enumerate([1,2,3,2]) if x==2 & 2<= i <=3] # -> [3]