【问题标题】:查找列表中项目的索引
【发布时间】:2010-09-15 16:04:50
【问题描述】:

给定一个列表 ["foo", "bar", "baz"] 和列表中的一个项目 "bar",我如何在 Python 中获取它的索引 (1)?

【问题讨论】:

  • 您是否返回:[1] 有多个"bar" 实例时的最低索引,[2] "bar" 的所有索引?
  • a) 是否保证项目在列表中,否则我们应该如何处理错误情况? (return None/raise ValueError) b) 是否保证列表条目是唯一的,我们应该返回匹配的第一个索引还是所有索引?
  • 通过 numpy 集成查看答案,numpy 数组比 Python 列表高效得多。如果列表很短,从 Python 列表中复制它是没有问题的,如果不是,那么也许您应该首先考虑将元素存储在 numpy 数组中。

标签: python list indexing


【解决方案1】:
>>> ["foo", "bar", "baz"].index("bar")
1

参考:Data Structures > More on Lists

注意事项

请注意,虽然这可能是回答问题的最简洁的方式按要求indexlist API 的一个相当薄弱的组件,我不记得最后一次我愤怒地使用它。在 cmets 中向我指出,因为这个答案被大量引用,所以它应该更完整。以下是关于list.index 的一些警告。最初可能值得看一下它的文档:

list.index(x[, start[, end]])

返回值等于 x 的第一个项目的列表中从零开始的索引。如果没有这样的项目,则引发ValueError

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

列表长度的线性时间复杂度

index 调用按顺序检查列表中的每个元素,直到找到匹配项。如果您的列表很长,并且您不知道它在列表中的大致位置,则此搜索可能会成为瓶颈。在这种情况下,您应该考虑不同的数据结构。请注意,如果您大致知道在哪里可以找到匹配项,您可以给index 一个提示。例如,在这个 sn-p 中,l.index(999_999, 999_990, 1_000_000) 比直接的 l.index(999_999) 快大约五个数量级,因为前者只需搜索 10 个条目,而后者搜索一百万个:

>>> 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

我曾经使用index 的大多数地方,现在我使用列表推导式或生成器表达式,因为它们更通用。因此,如果您正在考虑联系index,请查看这些出色的 Python 功能。

如果元素不在列表中则抛出

如果项目不存在,则调用index 会导致ValueError

>>> [1, 1].index(2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: 2 is not in list

如果该项目可能不在列表中,您也应该

  1. 首先使用item in my_list(干净、可读的方法)检查​​它,或者
  2. index 调用包装在一个捕获ValueErrortry/except 块中(可能更快,至少在要搜索的列表很长并且该项目通常存在时。)

【讨论】:

  • index 返回值为“bar”的第一项。如果“bar”在列表中存在两次,您将永远找不到第二个“bar”的键。请参阅文档:docs.python.org/3/tutorial/datastructures.html
  • 如果您只搜索一个元素(第一个),我发现index() 比针对整数列表的列表理解快 90%。
  • 如果列表很长,应该使用什么数据结构?
  • @izhang:一些辅助索引,如 {element -> list_index} 字典,如果元素是可散列的,并且列表中的位置很重要。
  • sequence1 = sorted(sequence2, key=.sequence3.index) 是一个非常方便的习语。如果您的曲目中有索引,您可能会更频繁地使用它。
【解决方案2】:

对学习 Python 真正有帮助的一件事是使用交互式帮助功能:

>>> help(["foo", "bar", "baz"])
Help on list object:

class list(object)
 ...

 |
 |  index(...)
 |      L.index(value, [start, [stop]]) -> integer -- return first index of value
 |

这通常会引导您找到您正在寻找的方法。

【讨论】:

  • bpython 是一种以交互方式阅读文档的用户友好方式。
  • @davidavr 是的,但是我们其他只想谷歌搜索而不是滚动浏览帮助文档的人不会有这么好的、中心的、排名的选项集。 :)
【解决方案3】:

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

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

def all_indices(value, qlist):
    indices = []
    idx = -1
    while True:
        try:
            idx = qlist.index(value, idx+1)
            indices.append(idx)
        except ValueError:
            break
    return indices

all_indices("foo", ["foo","bar","baz","foo"])

【讨论】:

【解决方案4】:
a = ["foo","bar","baz",'bar','any','much']

indexes = [index for index in range(len(a)) if a[index] == 'bar']

【讨论】:

【解决方案5】:

如果元素不在列表中,就会出现问题。这个函数处理这个问题:

# 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

【讨论】:

    【解决方案6】:

    这里提出的所有功能都重现了固有的语言行为,但掩盖了正在发生的事情。

    [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
    

    如果语言提供了方法来做你想做的事情,为什么还要编写一个带有异常处理的函数?

    【讨论】:

    • 第三种方法在列表上迭代两次,对吧?
    • 回复:“此处提出的所有功能”:可能在撰写本文时,但您应该检查更新的答案,看看它是否仍然正确。跨度>
    【解决方案7】:

    你可以一起去

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

    【讨论】:

      【解决方案8】:

      另一种选择

      >>> 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]
      >>> 
      

      【讨论】:

      【解决方案9】:

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

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

      index() 函数只返回第一个匹配项,而enumerate() 返回所有匹配项。

      作为列表理解:

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

      这里还有另一个使用 itertools.count() 的小解决方案(这与 enumerate 的方法几乎相同):

      from itertools import izip as zip, count # izip for maximum efficiency
      [i for i, j in zip(count(), ['foo', 'bar', 'baz']) if j == 'bar']
      

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

      $ python -m timeit -s "from itertools import izip as zip, count" "[i for i, j in zip(count(), ['foo', 'bar', 'baz']*500) if j == 'bar']"
      10000 loops, best of 3: 174 usec per loop
      $ python -m timeit "[i for i, j in enumerate(['foo', 'bar', 'baz']*500) if j == 'bar']"
      10000 loops, best of 3: 196 usec per loop
      

      【讨论】:

      • 对我来说,枚举比基于索引的方法效果更好,因为我希望使用 'startswith" 来收集字符串的索引,并且我需要收集多次出现的情况。或者有没有办法使用我无法弄清楚的“startswith”索引
      • 在我手中,枚举版本始终稍快一些。自上述测量结果发布以来,一些实施细节可能已发生变化。
      • 自 11 年以来已经回答了这个问题:stackoverflow.com/questions/6294179/…
      • 如此节省答案!谢谢!.. 在了解我们可以使用枚举之前,我尝试了 2 天来获取嵌套字典的索引
      【解决方案10】:

      获取所有索引:

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

      【讨论】:

      【解决方案11】:

      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 的次数,但不能保证效率。

      【讨论】:

      【解决方案12】:

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

      if 'your_element' in mylist:
          print mylist.index('your_element')
      else:
          print None
      

      【讨论】:

      • 这有助于我们避免try catch!
      • 但是,它可能会使复杂性加倍。有人查过吗?
      • @stefanct 时间复杂度仍然是线性的,但它会遍历列表两次。
      • @ApproachingDarknessFish 这显然是我的意思。即使从迂腐的角度来看,它的复杂性是相同的 order,但在许多用例中迭代两次可能是一个严重的劣势,因此我提出了它。而我们仍然不知道答案......
      • @stefanct 这可能会使复杂性增加一倍,我相信列表上的 in 运算符具有线性运行时。 @ApproachingDarknessFish 表示它会迭代两次以回答您的问题,并且正确地说将线性复杂度加倍并不是什么大问题。在许多用例中,我不会将迭代列表两次称为严重劣势,因为复杂性理论告诉我们 O(n) + O(n) -> O(2*n) -> O(n),即 -这种变化通常可以忽略不计。
      【解决方案13】:

      现在,为了完全不同的东西......

      ...就像在获取索引之前确认项目的存在。这种方法的好处是该函数总是返回一个索引列表——即使它是一个空列表。它也适用于字符串。

      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]
      >>> 
      

      现在,在查看了这个问题和所有答案之后,我意识到这正是FMc 在他的earlier answer 中所建议的。在我最初回答这个问题时,我什至没有看到那个答案,因为我不明白。我希望我更详细的示例将有助于理解。

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

      【讨论】:

        【解决方案14】:

        此解决方案不如其他解决方案强大,但如果您是初学者并且只知道forloops,仍然可以在避免 ValueError 的同时找到项目的第一个索引:

        def find_element(p,t):
            i = 0
            for e in p:
                if e == t:
                    return i
                else:
                    i +=1
            return -1
        

        【讨论】:

          【解决方案15】:
          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)
          

          这说明字符串是否不在列表中,如果它不在列表中则location = -1

          【讨论】:

            【解决方案16】:

            所有带有zip函数的索引:

            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')
            

            【讨论】:

            【解决方案17】:

            如果你想要所有索引,那么你可以使用NumPy:

            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),)
            

            这是清晰易读的解决方案。

            【讨论】:

            • 字符串列表、非数字对象列表等怎么样?
            • 这个答案最好贴在这里:stackoverflow.com/questions/6294179/…
            • 这是我读过的最好的一本。 numpy 数组比 Python 列表高效得多。如果列表很短,从 Python 列表中复制它是没有问题的,如果不是,那么也许开发人员应该首先考虑将元素存储在 numpy 数组中。
            【解决方案18】:

            获取列表中一个或多个(相同)项目的所有出现和位置

            使用 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]
            >>>
            

            让我们的函数 findindex

            这个函数将项目和列表作为参数,并返回项目在列表中的位置,就像我们之前看到的那样。

            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
            

            【讨论】:

            【解决方案19】:

            由于 Python 列表是从零开始的,我们可以使用 zip 内置函数如下:

            >>> [i for i,j in zip(range(len(haystack)), haystack) if j == 'needle' ]
            

            其中“haystack”是相关列表,“needle”是要查找的项目。

            (注意:这里我们使用 i 进行迭代以获取索引,但如果我们需要更专注于项目,我们可以切换到 j。)

            【讨论】:

            • [i for i,j in enumerate(haystack) if j=='needle'] 我认为更紧凑和可读。
            【解决方案20】:

            在 Python 中找到一个给定列表的项目的索引

            对于列表 ["foo", "bar", "baz"] 和列表中的项目 "bar",在 Python 中获取其索引 (1) 的最简洁方法是什么?

            好吧,当然,有 index 方法,它返回第一次出现的索引:

            >>> l = ["foo", "bar", "baz"]
            >>> l.index('bar')
            1
            

            这种方法有几个问题:

            • 如果该值不在列表中,您将获得ValueError
            • 如果列表中有多个值,则只能获取第一个的索引

            没有值

            如果该值可能丢失,您需要捕获ValueError

            您可以使用这样的可重用定义来做到这一点:

            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
            

            这样做的缺点是您可能会检查返回值是is 还是is not None:

            result = index(a_list, value)
            if result is not None:
                do_something(result)
            

            列表中有多个值

            如果你可以有更多的出现,你将不会通过list.index获得完整的信息:

            >>> 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)
            

            使用 pandas 更好地处理数据

            如果您有 pandas,则可以使用 Series 对象轻松获取此信息:

            >>> 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
            

            如果只需要索引,则 index 属性返回一系列整数:

            >>> series[series == 'bar'].index
            Int64Index([1, 3], dtype='int64')
            

            如果您希望它们在列表或元组中,只需将它们传递给构造函数即可:

            >>> list(series[series == 'bar'].index)
            [1, 3]
            

            是的,您也可以将列表推导式与 enumerate 一起使用,但在我看来,这并不优雅 - 您正在 Python 中进行相等性测试,而不是让用 C 编写的内置代码来处理它:

            >>> [i for i, value in enumerate(l) if value == 'bar']
            [1, 3]
            

            这是XY problem吗?

            XY 问题是询问您尝试的解决方案,而不是您的实际问题。

            为什么你认为你需要给定列表中的元素的索引?

            如果您已经知道值,为什么还要关心它在列表中的位置?

            如果该值不存在,捕获 ValueError 会相当冗长 - 我更愿意避免这种情况。

            我通常会遍历列表,所以我通常会保留指向任何有趣信息的指针,获取index with enumerate.

            如果您正在处理数据,您可能应该使用 pandas - 它拥有比我展示的纯 Python 变通方法更优雅的工具。

            我不记得自己需要list.index。但是,我浏览了 Python 标准库,发现它有一些出色的用途。

            idlelib 中有很多很多用途,用于 GUI 和文本解析。

            keyword 模块使用它来查找模块中的注释标记,以通过元编程自动重新生成其中的关键字列表。

            在 Lib/mailbox.py 中,它似乎像使用有序映射一样使用它:

            key_list[key_list.index(old)] = new
            

            del key_list[key_list.index(key)]
            

            在lib/http/cookiejar.py中,好像是用来获取下个月的:

            mon = MONTHS_LOWER.index(mon.lower())+1
            

            在类似于 distutils 的 Lib/tarfile.py 中获取一个项目的切片:

            members = members[:members.index(tarinfo)]
            

            在 Lib/pickletools.py 中:

            numtopop = before.index(markobject)
            

            这些用法的共同点似乎是它们似乎在限制大小的列表上运行(很重要,因为 list.index 的 O(n) 查找时间),并且它们主要用于解析(和 UI 中的空闲的情况)。

            虽然有它的用例,但它们并不常见。如果您发现自己正在寻找这个答案,请问问自己,您所做的是否是最直接地使用该语言为您的用例提供的工具。

            【讨论】:

              【解决方案21】:

              对于像我这样来自其他语言的人来说,也许通过一个简单的循环更容易理解和使用它:

              mylist = ["foo", "bar", "baz", "bar"]
              newlist = enumerate(mylist)
              for index, item in newlist:
                if item == "bar":
                  print(index, item)
              

              感谢So what exactly does enumerate do?。这有助于我理解。

              【讨论】:

                【解决方案22】:

                如果找不到该项目,Python index() 方法会引发错误。因此,您可以使其类似于 JavaScript 的 indexOf() 函数,如果找不到该项目,则返回 -1

                try:
                    index = array.index('search_keyword')
                except ValueError:
                    index = -1
                

                【讨论】:

                • 然而,JavaScript 的哲学是奇怪的结果比错误更好,所以返回 -1 是有意义的,但在 Python 中,它可能很难追踪错误,因为 -1 从列表末尾返回一个项目。
                【解决方案23】:

                对此有更实用的答案。

                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))))))
                

                【讨论】:

                • 这个答案让Scala/功能编程爱好者感到宾至如归
                • 当列表中只有一个值需要匹配很多匹配项时,这需要很长时间。
                【解决方案24】:

                在列表 L 中查找项目 x 的索引:

                idx = L.index(x) if (x in L) else -1
                

                【讨论】:

                • 这会迭代数组两次,因此可能会导致大型数组出现性能问题。
                【解决方案25】:

                如果关注性能:

                很多答案都提到list.index(item)方法的内置方法是O(n)算法。如果您需要执行一次,这很好。但是,如果您需要多次访问元素的索引,那么首先创建一个包含项目索引对的字典 (O(n)),然后在每次需要时访问 O(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]
                

                【讨论】:

                  【解决方案26】:

                  正如@TerryA 所指出的,许多答案都讨论了如何找到一个索引。

                  more_itertools 是一个第三方库,带有用于在可迭代对象中定位多个索引的工具。

                  给定

                  import more_itertools as mit
                  
                  
                  iterable = ["foo", "bar", "baz", "ham", "foo", "bar", "baz"]
                  

                  代码

                  查找多个观察的索引:

                  list(mit.locate(iterable, lambda x: x == "bar"))
                  # [1, 5]
                  

                  测试多个项目:

                  list(mit.locate(iterable, lambda x: x in {"bar", "ham"}))
                  # [1, 3, 5]
                  

                  还可以使用more_itertools.locate 查看更多选项。通过&gt; pip install more_itertools安装。

                  【讨论】:

                    【解决方案27】:

                    让我们将名称 lst 放到您拥有的列表中。可以将列表lst 转换为numpy array。然后,使用numpy.where 获取列表中所选项目的索引。以下是您实施它的方式。

                    import numpy as np
                    
                    lst = ["foo", "bar", "baz"]  #lst: : 'list' data type
                    print np.where( np.array(lst) == 'bar')[0][0]
                    
                    >>> 1
                    

                    【讨论】:

                    • 如果项目是类的实例则不起作用
                    【解决方案28】:

                    使用字典,首先处理列表,然后将索引添加到它

                    from collections import defaultdict
                    
                    index_dict = defaultdict(list)    
                    word_list =  ['foo','bar','baz','bar','any', 'foo', 'much']
                    
                    for word_index in range(len(word_list)) :
                        index_dict[word_list[word_index]].append(word_index)
                    
                    word_index_to_find = 'foo'       
                    print(index_dict[word_index_to_find])
                    
                    # output :  [0, 5]
                    

                    【讨论】:

                      【解决方案29】:

                      如果您要查找一次索引,那么使用“索引”方法就可以了。但是,如果您要多次搜索数据,那么我建议您使用bisect 模块。请记住,必须对使用 bisect 模块的数据进行排序。因此,您对数据进行一次排序,然后您可以使用 bisect。 在我的机器上使用bisect 模块比使用索引方法快大约 20 倍。

                      以下是使用 Python 3.8 及以上语法的代码示例:

                      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
                      

                      【讨论】:

                        【解决方案30】:

                        对于一个可比较的

                        # Throws ValueError if nothing is found
                        some_list = ['foo', 'bar', 'baz'].index('baz')
                        # some_list == 2
                        

                        自定义谓词

                        some_list = [item1, item2, item3]
                        
                        # Throws StopIteration if nothing is found
                        # *unless* you provide a second parameter to `next`
                        index_of_value_you_like = next(
                            i for i, item in enumerate(some_list)
                            if item.matches_your_criteria())
                        

                        通过谓词查找所有项目的索引

                        index_of_staff_members = [
                            i for i, user in enumerate(users)
                            if user.is_staff()]
                        

                        【讨论】:

                        • idx = next((i for i, v in enumerate(ls) if v == chk), -1) 获得类似于 str.index(chk) 的行为。
                        • @tejasvi88 决定在答案中做一些额外的工作
                        猜你喜欢
                        • 2016-01-25
                        • 2014-10-13
                        • 2023-02-11
                        • 1970-01-01
                        • 2020-07-20
                        • 1970-01-01
                        • 2013-01-07
                        • 2012-01-10
                        • 2018-07-31
                        相关资源
                        最近更新 更多