在列表中查找项目索引的最快方法?
Fastest way to find Indexes of item in list?
如果要尝试在列表中查找某项的索引,您可以采用几种不同的方法,我知道这是最快的方法:
aList = [123, 'xyz', 'zara','xyz', 'abc'];
indices = [i for i, x in enumerate(aList) if x == "xyz"]
print(indices)
另一种不是 pythonic 且速度较慢的方法:
count = 0
indices = []
aList = [123, 'xyz', 'zara','xyz', 'abc'];
for i in range(0,len(aList):
if 'xyz' == aList[i]:
indices.append(i)
print(indices)
第一种方法无疑更快,但是如果你想更快,有什么方法吗?对于使用方法的第一个索引:
aList = [123, 'xyz', 'zara','xyz', 'abc'];
print "Index for xyz : ", aList.index( 'xyz' )
速度非常快,但无法处理多个索引。
如何才能加快速度?
def find(target, myList):
for i in range(len(myList)):
if myList[i] == target:
yield i
def find_with_list(myList, target):
inds = []
for i in range(len(myList)):
if myList[i] == target:
inds += i,
return inds
In [8]: x = range(50)*200
In [9]: %timeit [i for i,j in enumerate(x) if j == 3]
1000 loops, best of 3: 598 us per loop
In [10]: %timeit list(find(3,x))
1000 loops, best of 3: 607 us per loop
In [11]: %timeit find(3,x)
1000000 loops, best of 3: 375 ns per loop
In [55]: %timeit find_with_list(x,3)
1000 loops, best of 3: 618 us per loop
假设您想要一个列表作为输出:
- 对于我的测试,所有选项似乎都表现出相似的时间性能,列表理解是最快的(勉强)。
如果可以接受使用生成器,它比其他方法要快得多。尽管它不考虑实际迭代索引,也不存储它们,因此不能对索引进行第二次迭代。
D=dict()
for i, item in enumerate(l):
if item not in D:
D[item] = [i]
else:
D[item].append(i)
然后只需调用 D[item] 即可获得匹配的索引。您将放弃初始计算时间,但会在调用期间获得它。
使用list.index(elem, start)
!它在 C 中使用了一个 for
循环(请参阅 CPython 的 listobject.c 的源代码中的实现 list_index_impl
函数)。
避免遍历 Python 中的所有元素,它比 C.
中慢
def index_finder(lst, item):
"""A generator function, if you might not need all the indices"""
start = 0
while True:
try:
start = lst.index(item, start)
yield start
start += 1
except ValueError:
break
import array
def index_find_all(lst, item, results=None):
""" If you want all the indices.
Pass results=[] if you explicitly need a list,
or anything that can .append(..)
"""
if results is None:
length = len(lst)
results = (array.array('B') if length <= 2**8 else
array.array('H') if length <= 2**16 else
array.array('L') if length <= 2**32 else
array.array('Q'))
start = 0
while True:
try:
start = lst.index(item, start)
results.append(start)
start += 1
except ValueError:
return results
# Usage example
l = [1, 2, 3, 4, 5, 6, 7, 8] * 32
print(*index_finder(l, 1))
print(*index_find_all(l, 1))
要获取项目的索引,可以使用字典。
aList = [123, 'xyz', 'zara','xyz', 'abc'];
#The following apporach works only on lists with unique values
aList = list(np.unique(aList));
dict = enumerate(aList);
# get inverse mapping of above dictionary, replace key with values
inv_dict = dict(zip(dict.values(),dict.keys()))
# to get index of item by value, use 'inv_dict' and to get value by index, use 'dict'
valueofItemAtIndex0 = dict[0]; # value = 123
indexofItemWithValue123 = inv_dict[123]; # index = 0
我用另一种方法在 Python 3 中的列表中查找元素的索引:
def index_of(elem, a):
a_e = enumerate(a)
a_f = list(filter(lambda x: x[1] == elem, a_e))
if a_f:
return a_f[0][0]
else:
return -1
一些测试:
a=[1,2,3,4,2]
index_of(2,a)
这个函数总是return第一次出现的元素。如果元素不在列表中,return -1。对于我的目标,该解决方案效果很好。
使用 zip 从项目列表简单地创建一个 item->index 的字典,如下所示:
items_as_dict = dict(zip(list_of_items,range(0,len(list_of_items))))
index = items_as_dict(item)
如果要尝试在列表中查找某项的索引,您可以采用几种不同的方法,我知道这是最快的方法:
aList = [123, 'xyz', 'zara','xyz', 'abc'];
indices = [i for i, x in enumerate(aList) if x == "xyz"]
print(indices)
另一种不是 pythonic 且速度较慢的方法:
count = 0
indices = []
aList = [123, 'xyz', 'zara','xyz', 'abc'];
for i in range(0,len(aList):
if 'xyz' == aList[i]:
indices.append(i)
print(indices)
第一种方法无疑更快,但是如果你想更快,有什么方法吗?对于使用方法的第一个索引:
aList = [123, 'xyz', 'zara','xyz', 'abc'];
print "Index for xyz : ", aList.index( 'xyz' )
速度非常快,但无法处理多个索引。
如何才能加快速度?
def find(target, myList):
for i in range(len(myList)):
if myList[i] == target:
yield i
def find_with_list(myList, target):
inds = []
for i in range(len(myList)):
if myList[i] == target:
inds += i,
return inds
In [8]: x = range(50)*200
In [9]: %timeit [i for i,j in enumerate(x) if j == 3]
1000 loops, best of 3: 598 us per loop
In [10]: %timeit list(find(3,x))
1000 loops, best of 3: 607 us per loop
In [11]: %timeit find(3,x)
1000000 loops, best of 3: 375 ns per loop
In [55]: %timeit find_with_list(x,3)
1000 loops, best of 3: 618 us per loop
假设您想要一个列表作为输出:
- 对于我的测试,所有选项似乎都表现出相似的时间性能,列表理解是最快的(勉强)。
如果可以接受使用生成器,它比其他方法要快得多。尽管它不考虑实际迭代索引,也不存储它们,因此不能对索引进行第二次迭代。
D=dict()
for i, item in enumerate(l):
if item not in D:
D[item] = [i]
else:
D[item].append(i)
然后只需调用 D[item] 即可获得匹配的索引。您将放弃初始计算时间,但会在调用期间获得它。
使用list.index(elem, start)
!它在 C 中使用了一个 for
循环(请参阅 CPython 的 listobject.c 的源代码中的实现 list_index_impl
函数)。
避免遍历 Python 中的所有元素,它比 C.
def index_finder(lst, item):
"""A generator function, if you might not need all the indices"""
start = 0
while True:
try:
start = lst.index(item, start)
yield start
start += 1
except ValueError:
break
import array
def index_find_all(lst, item, results=None):
""" If you want all the indices.
Pass results=[] if you explicitly need a list,
or anything that can .append(..)
"""
if results is None:
length = len(lst)
results = (array.array('B') if length <= 2**8 else
array.array('H') if length <= 2**16 else
array.array('L') if length <= 2**32 else
array.array('Q'))
start = 0
while True:
try:
start = lst.index(item, start)
results.append(start)
start += 1
except ValueError:
return results
# Usage example
l = [1, 2, 3, 4, 5, 6, 7, 8] * 32
print(*index_finder(l, 1))
print(*index_find_all(l, 1))
要获取项目的索引,可以使用字典。
aList = [123, 'xyz', 'zara','xyz', 'abc'];
#The following apporach works only on lists with unique values
aList = list(np.unique(aList));
dict = enumerate(aList);
# get inverse mapping of above dictionary, replace key with values
inv_dict = dict(zip(dict.values(),dict.keys()))
# to get index of item by value, use 'inv_dict' and to get value by index, use 'dict'
valueofItemAtIndex0 = dict[0]; # value = 123
indexofItemWithValue123 = inv_dict[123]; # index = 0
我用另一种方法在 Python 3 中的列表中查找元素的索引:
def index_of(elem, a):
a_e = enumerate(a)
a_f = list(filter(lambda x: x[1] == elem, a_e))
if a_f:
return a_f[0][0]
else:
return -1
一些测试:
a=[1,2,3,4,2]
index_of(2,a)
这个函数总是return第一次出现的元素。如果元素不在列表中,return -1。对于我的目标,该解决方案效果很好。
使用 zip 从项目列表简单地创建一个 item->index 的字典,如下所示:
items_as_dict = dict(zip(list_of_items,range(0,len(list_of_items))))
index = items_as_dict(item)