Python 在列表中查找项的索引

Python 在列表中查找项的索引,python,list,indexing,Python,List,Indexing,给定一个列表[“foo”,“bar”,“baz”]和列表中的一个项目“bar”,如何在Python中获取其索引(1) >>> ["foo", "bar", "baz"].index("bar") 1 参考: 警告随之而来 请注意,虽然这可能是回答问题的最简洁的方式,index是列表API的一个相当薄弱的组成部分,我不记得上一次愤怒地使用它是什么时候了。评论中向我指出,因为这个答案被大量引用,所以应

给定一个列表
[“foo”,“bar”,“baz”]
和列表中的一个项目
“bar”
,如何在Python中获取其索引(
1

>>> ["foo", "bar", "baz"].index("bar")
1
参考:

警告随之而来 请注意,虽然这可能是回答问题的最简洁的方式,
index
列表
API的一个相当薄弱的组成部分,我不记得上一次愤怒地使用它是什么时候了。评论中向我指出,因为这个答案被大量引用,所以应该更加完整。下面是关于
列表的一些注意事项。可能值得先看一下它的文档:

返回值等于x的第一项列表中从零开始的索引。如果没有此类项,则引发错误

可选参数start和end在中解释为,用于将搜索限制为列表的特定子序列。返回的索引是相对于完整序列的开头而不是起始参数计算的

列表长度的线性时间复杂度
index
调用按顺序检查列表中的每个元素,直到找到匹配项。如果您的列表很长,并且您不知道它在列表中的大致位置,那么此搜索可能会成为一个瓶颈。在这种情况下,您应该考虑不同的数据结构。请注意,如果您大致知道在哪里可以找到匹配项,您可以给
index
一个提示。例如,在这个代码片段中,
l.index(999\u 999\u 990,1\u 000\u 000)
比straight
l.index(999\u 999)
大约快五个数量级,因为前者只需搜索10个条目,而后者则搜索100万个条目:

>>> import timeit
>>> timeit.timeit('l.index(999_999)', setup='l = list(range(0, 1_000_000))', number=1000)
9.356267921015387
>>> timeit.timeit('l.index(999_999, 999_990, 1_000_000)', setup='l = list(range(0, 1_000_000))', number=1000)
0.0004404920036904514
 
仅将第一个匹配项的索引返回到其参数 调用
index
按顺序搜索列表,直到找到匹配项,然后停止。如果希望需要更多匹配项的索引,则应使用列表理解或生成器表达式

>>> [1, 1].index(1)
0
>>> [i for i, e in enumerate([1, 2, 1]) if e == 1]
[0, 2]
>>> g = (i for i, e in enumerate([1, 2, 1]) if e == 1)
>>> next(g)
0
>>> next(g)
2
在我曾经使用
索引的大多数地方,我现在使用列表理解或生成器表达式,因为它们更具一般性。因此,如果您正在考虑使用
索引
,请看看这些优秀的Python特性

如果元素不在列表中,则抛出 调用
索引
,如果项目不存在,则会导致错误

>>> [1, 1].index(2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: 2 is not in list
[1,1]。索引(2)
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
ValueError:2不在列表中
如果该项目可能不在列表中,您应该

  • 首先使用my_列表中的
    项检查它(干净、可读的方法),或
  • 索引
    调用包装在一个
    try/except
    块中,该块捕获
    ValueError
    (可能更快,至少当要搜索的列表很长且项目通常存在时。)

  • 在学习Python时真正有用的一件事是使用交互式帮助函数:

    >>> help(["foo", "bar", "baz"])
    Help on list object:
    
    class list(object)
     ...
    
     |
     |  index(...)
     |      L.index(value, [start, [stop]]) -> integer -- return first index of value
     |
    
    get_indexes = lambda x, xs: [i for (y, i) in zip(xs, range(len(xs))) if x == y]
    
    print get_indexes(2, [1, 2, 3, 4, 5, 6, 3, 2, 3, 2])
    print get_indexes('f', 'xsfhhttytffsafweef')
    
    这通常会引导您找到要查找的方法。

    index()
    返回值的第一个索引

    |索引(…)
    |L.index(value,[start,[stop]])->integer——返回值的第一个索引


    如果元素不在列表中,则会出现问题。此函数处理以下问题:

    # if element is found it returns index of element else returns None
    
    def find_element_in_list(element, list_element):
        try:
            index_element = list_element.index(element)
            return index_element
        except ValueError:
            return None
    

    这里提出的所有函数都再现了固有的语言行为,但掩盖了正在发生的事情

    [i for i in range(len(mylist)) if mylist[i]==myterm]  # get the indices
    
    [each for each in mylist if each==myterm]             # get the items
    
    mylist.index(myterm) if myterm in mylist else None    # get the first index and fail quietly
    
    如果语言本身提供了执行所需操作的方法,那么为什么要编写带有异常处理的函数呢?

    您可以简单地使用它

    a = [['hand', 'head'], ['phone', 'wallet'], ['lost', 'stock']]
    b = ['phone', 'lost']
    
    res = [[x[0] for x in a].index(y) for y in b]
    
    另一种选择

    >>> a = ['red', 'blue', 'green', 'red']
    >>> b = 'red'
    >>> offset = 0;
    >>> indices = list()
    >>> for i in range(a.count(b)):
    ...     indices.append(a.index(b,offset))
    ...     offset = indices[-1]+1
    ... 
    >>> indices
    [0, 3]
    >>> 
    

    大多数答案解释了如何查找单个索引,但是如果项目多次出现在列表中,他们的方法不会返回多个索引。使用:

    index()
    函数只返回第一次出现的情况,而
    enumerate()
    函数返回所有出现的情况

    作为一个列表:

    [i for i, j in enumerate(['foo', 'bar', 'baz']) if j == 'bar']
    

    这里还有另一个小型解决方案(与enumerate的方法几乎相同):

    对于较大的列表,这比使用
    enumerate()
    更有效:

    要获取所有索引,请执行以下操作:

    indexes = [i for i,x in enumerate(xs) if x == 'foo']
    

    FMc和user7177答案的变体将给出一个dict,可以返回任何条目的所有索引:

    >>> a = ['foo','bar','baz','bar','any', 'foo', 'much']
    >>> l = dict(zip(set(a), map(lambda y: [i for i,z in enumerate(a) if z is y ], set(a))))
    >>> l['foo']
    [0, 5]
    >>> l ['much']
    [6]
    >>> l
    {'baz': [2], 'foo': [0, 5], 'bar': [1, 3], 'any': [4], 'much': [6]}
    >>> 
    

    您还可以将其用作一个线性函数,以获取单个条目的所有索引。虽然我确实使用了set(a)来减少lambda的调用次数,但效率没有保证。

    您必须设置一个条件来检查您正在搜索的元素是否在列表中

    if 'your_element' in mylist:
        print mylist.index('your_element')
    else:
        print None
    
    现在,为了一些完全不同的东西。。。 。。。比如在获取索引之前确认项目的存在。这种方法的优点是函数总是返回一个索引列表——即使它是一个空列表。它也适用于字符串

    def indices(l, val):
        """Always returns a list containing the indices of val in the_list"""
        retval = []
        last = 0
        while val in l[last:]:
                i = l[last:].index(val)
                retval.append(last + i)
                last += i + 1   
        return retval
    
    l = ['bar','foo','bar','baz','bar','bar']
    q = 'bar'
    print indices(l,q)
    print indices(l,'bat')
    print indices('abcdaababb','a')
    
    粘贴到交互式python窗口时:

    Python 2.7.6 (v2.7.6:3a1db0d2747e, Nov 10 2013, 00:42:54) 
    [GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
    Type "help", "copyright", "credits" or "license" for more information.
    >>> def indices(the_list, val):
    ...     """Always returns a list containing the indices of val in the_list"""
    ...     retval = []
    ...     last = 0
    ...     while val in the_list[last:]:
    ...             i = the_list[last:].index(val)
    ...             retval.append(last + i)
    ...             last += i + 1   
    ...     return retval
    ... 
    >>> l = ['bar','foo','bar','baz','bar','bar']
    >>> q = 'bar'
    >>> print indices(l,q)
    [0, 2, 4, 5]
    >>> print indices(l,'bat')
    []
    >>> print indices('abcdaababb','a')
    [0, 4, 5, 7]
    >>> 
    
    更新 在又一年的python开发之后,我对我最初的答案感到有点尴尬,所以为了澄清事实,我们当然可以使用上面的代码;但是,获得相同行为的更惯用的方法是使用列表理解以及enumerate()函数

    大概是这样的:

    def indices(l, val):
        """Always returns a list containing the indices of val in the_list"""
        return [index for index, value in enumerate(l) if value == val]
    
    l = ['bar','foo','bar','baz','bar','bar']
    q = 'bar'
    print indices(l,q)
    print indices(l,'bat')
    print indices('abcdaababb','a')
    
    当粘贴到交互式python窗口时,会产生:

    Python 2.7.14 |Anaconda, Inc.| (default, Dec  7 2017, 11:07:58) 
    [GCC 4.2.1 Compatible Clang 4.0.1 (tags/RELEASE_401/final)] on darwin
    Type "help", "copyright", "credits" or "license" for more information.
    >>> def indices(l, val):
    ...     """Always returns a list containing the indices of val in the_list"""
    ...     return [index for index, value in enumerate(l) if value == val]
    ... 
    >>> l = ['bar','foo','bar','baz','bar','bar']
    >>> q = 'bar'
    >>> print indices(l,q)
    [0, 2, 4, 5]
    >>> print indices(l,'bat')
    []
    >>> print indices('abcdaababb','a')
    [0, 4, 5, 7]
    >>> 
    
    现在,在回顾了这个问题和所有答案之后,我意识到这正是他在书中提出的。在我最初回答这个问题的时候,我甚至没有看到这个答案,因为我不理解它。我希望我更详细的例子有助于理解


    如果上面的一行代码对您仍然没有意义,我强烈建议您在谷歌上搜索“python列表理解”,并花几分钟时间熟悉一下自己。这只是使用Python开发代码的众多强大功能之一。

    此解决方案不如其他解决方案强大,但如果您是初学者且仅限于
    if 'your_element' in mylist:
        print mylist.index('your_element')
    else:
        print None
    
    def indices(l, val):
        """Always returns a list containing the indices of val in the_list"""
        retval = []
        last = 0
        while val in l[last:]:
                i = l[last:].index(val)
                retval.append(last + i)
                last += i + 1   
        return retval
    
    l = ['bar','foo','bar','baz','bar','bar']
    q = 'bar'
    print indices(l,q)
    print indices(l,'bat')
    print indices('abcdaababb','a')
    
    Python 2.7.6 (v2.7.6:3a1db0d2747e, Nov 10 2013, 00:42:54) 
    [GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
    Type "help", "copyright", "credits" or "license" for more information.
    >>> def indices(the_list, val):
    ...     """Always returns a list containing the indices of val in the_list"""
    ...     retval = []
    ...     last = 0
    ...     while val in the_list[last:]:
    ...             i = the_list[last:].index(val)
    ...             retval.append(last + i)
    ...             last += i + 1   
    ...     return retval
    ... 
    >>> l = ['bar','foo','bar','baz','bar','bar']
    >>> q = 'bar'
    >>> print indices(l,q)
    [0, 2, 4, 5]
    >>> print indices(l,'bat')
    []
    >>> print indices('abcdaababb','a')
    [0, 4, 5, 7]
    >>> 
    
    def indices(l, val):
        """Always returns a list containing the indices of val in the_list"""
        return [index for index, value in enumerate(l) if value == val]
    
    l = ['bar','foo','bar','baz','bar','bar']
    q = 'bar'
    print indices(l,q)
    print indices(l,'bat')
    print indices('abcdaababb','a')
    
    Python 2.7.14 |Anaconda, Inc.| (default, Dec  7 2017, 11:07:58) 
    [GCC 4.2.1 Compatible Clang 4.0.1 (tags/RELEASE_401/final)] on darwin
    Type "help", "copyright", "credits" or "license" for more information.
    >>> def indices(l, val):
    ...     """Always returns a list containing the indices of val in the_list"""
    ...     return [index for index, value in enumerate(l) if value == val]
    ... 
    >>> l = ['bar','foo','bar','baz','bar','bar']
    >>> q = 'bar'
    >>> print indices(l,q)
    [0, 2, 4, 5]
    >>> print indices(l,'bat')
    []
    >>> print indices('abcdaababb','a')
    [0, 4, 5, 7]
    >>> 
    
    def find_element(p,t):
        i = 0
        for e in p:
            if e == t:
                return i
            else:
                i +=1
        return -1
    
    name ="bar"
    list = [["foo", 1], ["bar", 2], ["baz", 3]]
    new_list=[]
    for item in list:
        new_list.append(item[0])
    print(new_list)
    try:
        location= new_list.index(name)
    except:
        location=-1
    print (location)
    
    get_indexes = lambda x, xs: [i for (y, i) in zip(xs, range(len(xs))) if x == y]
    
    print get_indexes(2, [1, 2, 3, 4, 5, 6, 3, 2, 3, 2])
    print get_indexes('f', 'xsfhhttytffsafweef')
    
    import numpy as np
    
    array = [1, 2, 1, 3, 4, 5, 1]
    item = 1
    np_array = np.array(array)
    item_index = np.where(np_array==item)
    print item_index
    # Out: (array([0, 2, 6], dtype=int64),)
    
    >>> 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
    
    >>> [i for i,j in zip(range(len(haystack)), haystack) if j == 'needle' ]
    
    >>> l = ["foo", "bar", "baz"]
    >>> l.index('bar')
    1
    
    def index(a_list, value):
        try:
            return a_list.index(value)
        except ValueError:
            return None
    
    >>> print(index(l, 'quux'))
    None
    >>> print(index(l, 'bar'))
    1
    
    result = index(a_list, value)
    if result is not None:
        do_something(result)
    
    >>> l.append('bar')
    >>> l
    ['foo', 'bar', 'baz', 'bar']
    >>> l.index('bar')              # nothing at index 3?
    1
    
    >>> [index for index, v in enumerate(l) if v == 'bar']
    [1, 3]
    >>> [index for index, v in enumerate(l) if v == 'boink']
    []
    
    indexes = [index for index, v in enumerate(l) if v == 'boink']
    for index in indexes:
        do_something(index)
    
    >>> import pandas as pd
    >>> series = pd.Series(l)
    >>> series
    0    foo
    1    bar
    2    baz
    3    bar
    dtype: object
    
    >>> series == 'bar'
    0    False
    1     True
    2    False
    3     True
    dtype: bool
    
    >>> series[series == 'bar']
    1    bar
    3    bar
    dtype: object
    
    >>> series[series == 'bar'].index
    Int64Index([1, 3], dtype='int64')
    
    >>> list(series[series == 'bar'].index)
    [1, 3]
    
    >>> [i for i, value in enumerate(l) if value == 'bar']
    [1, 3]
    
    key_list[key_list.index(old)] = new
    
    del key_list[key_list.index(key)]
    
    mon = MONTHS_LOWER.index(mon.lower())+1
    
    members = members[:members.index(tarinfo)]
    
    numtopop = before.index(markobject)
    
    mylist = ["foo", "bar", "baz", "bar"]
    newlist = enumerate(mylist)
    for index, item in newlist:
      if item == "bar":
        print(index, item)
    
    try:
        index = array.index('search_keyword')
    except ValueError:
        index = -1
    
    list(filter(lambda x: x[1]=="bar",enumerate(["foo", "bar", "baz", "bar", "baz", "bar", "a", "b", "c"])))
    
    def get_index_of(lst, element):
        return list(map(lambda x: x[0],\
           (list(filter(lambda x: x[1]==element, enumerate(lst))))))
    
    idx = L.index(x) if (x in L) else -1
    
    myList = ["foo", "bar", "baz"]
    
    # Create the dictionary
    myDict = dict((e,i) for i,e in enumerate(myList))
    
    # Lookup
    myDict["bar"] # Returns 1
    # myDict.get("blah") if you don't want an error to be raised if element not found.
    
    from collections import defaultdict as dd
    myList = ["foo", "bar", "bar", "baz", "foo"]
    
    # Create the dictionary
    myDict = dd(list)
    for i,e in enumerate(myList):
        myDict[e].append(i)
    
    # Lookup
    myDict["foo"] # Returns [0, 4]
    
    import numpy as np
    
    lst = ["foo", "bar", "baz"]  #lst: : 'list' data type
    print np.where( np.array(lst) == 'bar')[0][0]
    
    >>> 1
    
    import bisect
    from timeit import timeit
    
    def bisect_search(container, value):
        return (
          index 
          if (index := bisect.bisect_left(container, value)) < len(container) 
          and container[index] == value else -1
        )
    
    data = list(range(1000))
    # value to search
    value = 666
    
    # times to test
    ttt = 1000
    
    t1 = timeit(lambda: data.index(value), number=ttt)
    t2 = timeit(lambda: bisect_search(data, value), number=ttt)
    
    print(f"{t1=:.4f}, {t2=:.4f}, diffs {t1/t2=:.2f}")
    
    t1=0.0400, t2=0.0020, diffs t1/t2=19.60
    
    list =  ["foo", "bar", "baz"]
    
    item_to_find = "foo"
    
    if item_to_find in list:
          index = list.index(item_to_find)
          print("Index of the item is " + str(index))
    else:
        print("That word does not exist")