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

32 投票
7 回答
61645 浏览
提问于 2025-04-17 21:24

给定:

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

每次出现的 s 在以下位置:

第一次: 2
第二次: 3
第三次: 4
第四次: 7

如果我使用 x.index('s'),我会得到第一个 s 的位置。

那么我该怎么才能找到第四个 s 的位置呢?

7 个回答

0

这里有一个更符合Python风格的方法,使用了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()函数传一个默认值,这样在找不到匹配时就会返回这个默认值,而不是抛出异常。

1

在编程中,有时候我们需要让程序在特定的条件下执行某些操作。比如说,如果你想让程序在某个变量的值达到特定数字时,才执行某个功能,这就需要用到条件判断。

条件判断就像是在问一个问题:“如果这个条件成立,我就做这件事;如果不成立,我就做另一件事。”这样可以让程序更灵活,能够根据不同的情况做出不同的反应。

在代码中,条件判断通常用“if”这个词来表示。你可以想象成一个开关,只有在条件满足的时候,这个开关才会打开,程序才会执行你想要的操作。

例如,如果你有一个数字变量,想要检查它是否大于10,你可以写一个条件判断来实现这个功能。如果这个变量的值确实大于10,程序就会执行你设定的操作;如果不是,程序就会跳过这一步。

这样一来,程序就能根据不同的输入做出不同的反应,变得更加智能和实用。

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))
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']
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 的行为更一致了。

34

使用列表推导式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

撰写回答