我想找到字符串中任何“特殊”字符第一次出现的索引,如下所示:
>>> "Hello world!".index([' ', '!'])
5
…除非那不是有效的 Python 语法。当然,我可以编写一个函数来模拟这种行为:
def first_index(s, characters):
i = []
for c in characters:
try:
i.append(s.index(c))
except ValueError:
pass
if not i:
raise ValueError
return min(i)
我也可以使用正则表达式,但这两种解决方案似乎都有些矫枉过正。在 Python 中有什么“合理”的方法可以做到这一点吗?
最佳答案
您可以使用 enumerate和 next用generator expression , 如果没有字符出现在 s: 中,则获取第一个匹配项或返回 None:
s = "Hello world!"
st = {"!"," "}
ind = next((i for i, ch in enumerate(s) if ch in st),None)
print(ind)
如果没有匹配项,您可以将任何您想要的值作为默认返回值传递给下一个。
如果您想使用函数并引发 ValueError:
def first_index(s, characters):
st = set(characters)
ind = next((i for i, ch in enumerate(s) if ch in st), None)
if ind is not None:
return ind
raise ValueError
对于较小的输入,使用集合不会有太大区别,但对于较大的字符串,它会更有效率。
一些时间:
字符串中,字符集的最后一个字符:
In [40]: s = "Hello world!" * 100
In [41]: string = s
In [42]: %%timeit
st = {"x","y","!"}
next((i for i, ch in enumerate(s) if ch in st), None)
....:
1000000 loops, best of 3: 1.71 µs per loop
In [43]: %%timeit
specials = ['x', 'y', '!']
min(map(lambda x: (string.index(x) if (x in string) else len(string)), specials))
....:
100000 loops, best of 3: 2.64 µs per loop
不在字符串中,更大的字符集:
In [44]: %%timeit
st = {"u","v","w","x","y","z"}
next((i for i, ch in enumerate(s) if ch in st), None)
....:
1000000 loops, best of 3: 1.49 µs per loop
In [45]: %%timeit
specials = ["u","v","w","x","y","z"]
min(map(lambda x: (string.index(x) if (x in string) else len(string)), specials))
....:
100000 loops, best of 3: 5.48 µs per loop
字符串中字符集的第一个字符:
In [47]: %%timeit
specials = ['H', 'y', '!']
min(map(lambda x: (string.index(x) if (x in string) else len(string)), specials))
....:
100000 loops, best of 3: 2.02 µs per loop
In [48]: %%timeit
st = {"H","y","!"}
next((i for i, ch in enumerate(s) if ch in st), None)
....:
1000000 loops, best of 3: 903 ns per loop
关于python - 如何找到字符串中任何一组字符的第一个索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30020184/