如何在列表中找到某个元素第n次出现的索引?

30

给定:

x = ['w', 'e', 's', 's', 's', 'z','z', 's']

每个 s 的出现位置如下:

第1个:2
第2个:3
第3个:4
第4个:7

如果我执行 x.index('s'),我会得到第1个索引。

我该如何获得第4个 s 的索引?


1
可能是 https://dev59.com/IHI-5IYBdhLWcg3wYnSQ 的重复。 - Pavan Gupta
7个回答

31

使用列表推导式enumerate函数:

>>> x = [ 'w', 'e', 's', 's', 's', 'z','z', 's']
>>> [i for i, n in enumerate(x) if n == 's'][0]
2
>>> [i for i, n in enumerate(x) if n == 's'][1]
3
>>> [i for i, n in enumerate(x) if n == 's'][2]
4
>>> [i for i, n in enumerate(x) if n == 's'][3]
7

11

如果您不想为每个出现的位置存储索引,或者想要处理任意可迭代对象,则可以使用类似以下的代码:

from itertools import islice

def nth_index(iterable, value, n):
    matches = (idx for idx, val in enumerate(iterable) if val == value)
    return next(islice(matches, n-1, n), None)

x = [ 'w', 'e', 's', 's', 's', 'z','z', 's']
idx = nth_index(x, 's', 4)
# 7

请注意在next中有一个默认值为None。您可能希望将其更改为其他值,或者将其删除并捕获StopIteration并作为另一个更合适的异常引发(例如ValueError),以便更好地与list.index行为相匹配。


4

获取项目的索引:

return [index for index, char in enumerate(x) if char == 's']

获取字符本身的方法如下:
return [char for index, char in enumerate(x) if char == 's']

或者获取字符/索引对的元组: (感谢falsetru指出了更简单的解决方案)
pairs = [(index, char) for index, char in enumerate(x) if char == 's']

enumerate 会产生 索引-元素 对,而不是 元素-索引 对。而 [char, index for ...] 则会导致语法错误。 - falsetru
糟糕,我的错,让我来修复。 - samrap
最后的代码可以替换为pairs = [(index, char) for index, char in enumerate(x) if char == 's']或者pairs = [pair for pair in enumerate(x) if pair[1] == 's'] - falsetru

1
def find_nth_character(str1, substr, n):
    """find the index of the nth substr in string str1""" 
    k = 0
    for index, c in enumerate(str1):
        #print index, c, n  # test
        if c == substr:
            k += 1
            if k == n:
                return index


str1 = "B.765.A87_43.Left.9878.xx8"
substr = '.'
occurance = 4

print "%s #%d at index %d" % (substr, occurance, find_nth_character(str1, substr, occurance))

0
这里有一个更加Pythonic的方法,使用itertools.count和生成器表达式:
In [24]: def get_nth_index(lst, item, n):
    ...:     c = count()
    ...:     return next(i for i, j in enumerate(x) if j=='s' and next(c) == n-1)

演示:

In [25]: get_nth_index(x, 's', 2)
Out[25]: 3

In [26]: get_nth_index(x, 's', 3)
Out[26]: 4

In [27]: get_nth_index(x, 's', 4)
Out[27]: 7

In [28]: get_nth_index(x, 's', 5)
---------------------------------------------------------------------------
StopIteration                             Traceback (most recent call last)
<ipython-input-28-fc4e5e8c31ef> in <module>()
----> 1 get_nth_index(x, 's', 5)

<ipython-input-24-5394f79b3c30> in get_nth_index(lst, item, n)
      1 def get_nth_index(lst, item, n):
      2     c = count()
----> 3     return next(i for i, j in enumerate(x) if j=='s' and next(c) == n-1)

StopIteration: 

In [29]: 

正如您所看到的,如果找不到匹配项,它将引发一个StopIteration异常。您还可以向next()函数传递一个默认参数,以返回默认值而不是引发异常。


0

你可以使用这个函数来查找最后一个位置

其中a是数组

t=(a.index(0)+a.count(0))-1

你可以将数字增加到-2或-3,以查找所需数字的倒数位置

注意:列表必须排序。您可以使用sort()进行排序

eg: a.sort()

点击此处了解更多列表内置函数


0

我们可以通过继承内置的列表类来简单地扩展其功能。

In [64]: class List(list):
       :     def __init__(self, *val):
       :         self.extend(list(val))
       :
       :
       :     def findidx(self, val, n=None):
       :         '''return the occurances of an object in a list'''
       :
       :         if n == None:
       :             return [i for i, v in enumerate(self) if v == val]
       :
       :         return [i for i, v in enumerate(self) if v == val][n]

有两种使用这个类的方法。请看下面的例子以了解。

In [65]: c = List(4, 5, 6, 7, 2, 5, 4 ,4) # enter the elements of the list as a argument

In [69]: c.findidx(4, 0) # search 4's 0th(1) occurance
Out[69]: 0

In [72]: c.findidx(4, 1) # find 4's 1st(2) occurance
Out[72]: 6

或者

In [66]: c.findidx(4) # find all occurances of 4
Out[66]: [0, 6, 7]

In [67]: c.findidx(4)[0] # first occurance
Out[67]: 0

In [67]: c.findidx(4)[2] # third occurance
Out[67]: 7

In [69]: c[0]# for verification
Out[69]: 4

In [70]: c[7]
Out[70]: 4

`


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接