首页 文章

在Python中查找包含它的列表的项目索引

提问于
浏览
2424

对于列表 ["foo", "bar", "baz"] 和列表 "bar" 中的项目,如何在Python中获取其索引(1)?

28 回答

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

  • 42

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

    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? . 这让我明白了 .

  • 0

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

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

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

    这种方法存在一些问题:

    • 如果值为't in the list, you' ll得到一个 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
    

    而这样做的缺点是你可能会检查返回值 isis not 无:

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

    列表中有多个值

    如果您可能有更多事件发生,您将 not 获取 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,可以使用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]
    

    是的,你也可以使用枚举的列表理解,但是在我看来,这不是那么优雅 - 你在Python中进行相等的测试,而不是让用C编写的内置代码处理它:

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

    这是XY问题吗?

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

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

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

    如果值不存在,那么 grab ValueError 就相当冗长了 - 我宁愿避免这种情况 .

    我'm usually iterating over the list anyways, so I' ll通常会指向任何有趣的信息,得到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
    

    在Lib / tarfile.py中类似于distutils来获取切片到项目:

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

    在Lib / pickletools.py中:

    numtopop = before.index(markobject)
    

    这些用法似乎有共同之处在于它们似乎在约束大小的列表上运行(因为 list.index 的O(n)查找时间很重要),并且它们主要用于解析(以及空闲时的UI) .

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

  • 15

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

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

    其中“haystack”是有问题的列表,“needle”是要查找的项目 .

    (注意:这里我们使用i来迭代获取索引,但如果我们需要关注项目,我们可以切换到j . )

  • 15

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

    使用enumerate(alist),当元素x等于您查找的内容时,您可以存储第一个元素(n),它是列表的索引 .

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

    Output


    [1, 3, 5, 7]
    

    简单

    for n, i in enumerate([1, 2, 3, 4, 1]):
        if i == 1:
            print(n)
    

    输出:

    0
    4
    
  • 60

    你可以随便去

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

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

    # 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
    
  • 13

    您必须设置条件以检查您要搜索的元素是否在列表中

    if 'your_element' in mylist:
        print mylist.index('your_element')
    else:
        print None
    
  • 69
    >>> ["foo", "bar", "baz"].index("bar")
    1
    

    参考:Data Structures > More on Lists

    警告如下

    请注意,尽管这可能是回答问题的最简洁方法,但 indexlist API的一个相当弱的组件,我可以't remember the last time I used it in anger. It'在评论中向我指出,因为这个答案被大量引用,所以应该更加完整 . 关于 list.index 的一些警告如下 . 最初可能需要查看文档字符串:

    >>> print(list.index.__doc__)
    L.index(value, [start, [stop]]) -> integer -- return first index of value.
    Raises ValueError if the value is not present.
    

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

    index 调用按顺序检查列表中的每个元素,直到找到匹配项 . 如果您的列表很长,并且您不清楚列表中的大致位置,则此搜索可能会成为瓶颈 . 在这种情况下,您应该考虑不同的数据结构 . 请注意,如果您大致知道匹配的位置,则可以给出 index 提示 . 例如,在这个片段中, 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
    

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

    • 首先使用 item in my_list (干净,可读的方法)检查它,或者

    • index 呼叫包裹在 try/except 块中,该块捕获 ValueError (可能更快,至少当搜索列表很长时,该项目通常存在 . )

  • 2

    对此有一个更实用的答案 .

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

    如果列表没有您需要检查索引的重复项,则有两种可能性

    eg: li=[10,20,30] # here need to get index of 20 means
         li.index(20) # will work properly because 20 is not repeated
    

    如果它的重复意味着它只会给你第一个索引

    如果您需要获取项目所在的所有索引,则表示

    eg: li=[10,20,30,20,40, 50, 10] # here need to get index of 20 means its have 2 index (1,3)
    

    得到你需要这样做

    li=[10,20,30,20,40, 50, 10]
     [i for i, e in enumerate(li) if e == 20]
    

    然后你会得到一个索引列表为o / p,如[1,3]

  • 0

    让我们将名称 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
    
  • 3560

    获取所有索引:

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

    如果表现令人担忧:

    在许多答案中都提到 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]
    
  • 23

    如果您想要所有索引,那么您可以使用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),)
    

    它是清晰易读的解决方案 .

  • 136

    这里提出的所有函数都重现了固有的语言行为,但却模糊了正在发生的事情 .

    [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
    

    如果语言提供了自己想做的方法,为什么要编写一个带异常处理的函数?

  • 13

    大多数答案解释了如何查找 a single index ,但是如果项目在列表中多次,则它们的方法不会返回多个索引 . 使用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()的另一个小解决方案(与枚举几乎相同):

    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
    
  • 37
    a = ["foo","bar","baz",'bar','any','much']
    
    indexes = [index for index in range(len(a)) if a[index] == 'bar']
    
  • 31

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

    more_itertools是第三方库,其中包含用于在可迭代内定位多个索引的工具 .

    Given

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

    Code

    查找多个观察的索引:

    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的更多选项 . 通过> pip install more_itertools安装 .

  • 19

    index() 返回 first 值的索引!

    | 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"])
    
  • 5

    具有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')
    
  • 3

    这个解决方案没有其他解决方案那么强大,但是如果你是初学者并且只知道 for 循环,那么在避免ValueError时仍然可以找到项目的第一个索引:

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

    来自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被调用的次数,但是效率没有保证 .

  • 1

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

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

    另外一个选项

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

    如果找不到该项,Python index() 方法会抛出错误,这很糟糕!

    所以你可以使它类似于JavaScript的 indexOf() 函数,如果找不到该项,它将返回 -1

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

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

    >>> help(["foo", "bar", "baz"])
    Help on list object:
    
    class list(object)
     ...
    
     |
     |  index(...)
     |      L.index(value, [start, [stop]]) -> integer -- return first index of value
     |
    

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

  • 2

    现在,对于完全不同的东西......

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

    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中所建议的 . 当我最初回答这个问题时,我甚至没有看到答案,因为我不明白 . 我希望我的一些更冗长的例子能够帮助理解 .

    如果上面的单行代码对您没有意义,我强烈建议您使用Google 'python list comprehension'并花几分钟时间熟悉自己 . 它只是使用Python开发代码的许多强大功能之一 .

相关问题