Python在列表中查找项目索引的最快方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/35640780/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 16:44:40  来源:igfitidea点击:

Python Fastest way to find Indexes of item in list

pythonperformancelistindexing

提问by Tyler Cowan

If one was to attempt to find the indexes of an item in a list you could do it a couple different ways here is what I know to be the fastest

如果要尝试在列表中查找项目的索引,您可以通过几种不同的方式来完成,这是我所知道的最快的方法

aList = [123, 'xyz', 'zara','xyz', 'abc']; 
indices = [i for i, x in enumerate(aList) if x == "xyz"]
print(indices)

Another way not pythonic and slower

另一种不是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)

the first method is undoubtedly faster however what if you wanted to go faster is there a way? for the first index using method

第一种方法无疑更快,但是如果你想更快,有什么办法吗?对于第一个索引使用方法

aList = [123, 'xyz', 'zara','xyz', 'abc'];             
print "Index for xyz : ", aList.index( 'xyz' ) 

is very fast but cant handle multiple indexes How might one go about speeding things up?

速度非常快,但无法处理多个索引 如何加快速度?

采纳答案by Garrett R

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

Assuming you want a list as your output: All options seemed exhibit similar time performance for my test with the list comprehension being the fastest (barely).

假设你想要一个列表作为你的输出:所有选项似乎在我的测试中表现出相似的时间性能,列表理解是最快的(几乎没有)。

And if you're cool with returning a generator, it's way faster than the other approaches. Thought it doesn't account for actually iterating over the indices, nor does it store them, so the inds cannot be iterated over a second time.

如果你对返回发电机很酷,它比其他方法快得多。认为它不考虑实际迭代索引,也不存储它们,因此不能第二次迭代索引。

回答by John

D=dict()
for i, item in enumerate(l):
    if item not in D:
        D[item] = [i]
    else:
        D[item].append(i)

Then simply call D[item] to get the indices that match. You'll give up initial calculation time but gain it during call time.

然后只需调用 D[item] 来获取匹配的索引。您将放弃初始计算时间,但会在调用期间获得它。

回答by poke53280

Use list.index(elem, start)! That uses a for loop in C (see it's implementation list_index_implfunction in the source of CPython's listobject.c). Avoid looping through all the elements in Python, it is slower than in C.

使用list.index(elem, start)!它在 C 中使用 for 循环(请参阅list_index_implCPython 的listobject.c源代码中的实现函数)。避免循环遍历 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))

回答by Harish Mashetty

To get the index of the item, you can use the dictionary.

要获取项目的索引,您可以使用字典。

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

回答by ?ngelo Polotto

I used another way to find the index of a element in a list in Python 3:

我使用另一种方法在 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

Some tests:

一些测试:

a=[1,2,3,4,2]
index_of(2,a)

This function always return the first occurrence of the element. If element ins't in the list, return -1. For my goals, that solution worked well.

这个函数总是返回元素的第一次出现。如果元素不在列表中,则返回 -1。对于我的目标,该解决方案运行良好。

回答by Ahmedov

Simply create a dictionary of item->index from the list of items using zip like so:

只需使用 zip 从项目列表中创建一个 item->index 字典,如下所示:

items_as_dict = dict(zip(list_of_items,range(0,len(list_of_items))))
index = items_as_dict(item)