如何找到字符串中任何一组字符的第一个索引 [英] How to find the first index of any of a set of characters in a string

查看:17
本文介绍了如何找到字符串中任何一组字符的第一个索引的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想找到字符串中任何特殊"字符第一次出现的索引,如下所示:

<预><代码>>>>"Hello world!".index([' ', '!'])5

...除了这不是有效的 Python 语法.当然,我可以写一个函数来模拟这种行为:

def first_index(s, characters):我 = []对于 c 字符:尝试:i.append(s.index(c))除了值错误:经过如果不是我:引发值错误返回 min(i)

我也可以使用正则表达式,但两种解决方案似乎都有些矫枉过正.在 Python 中是否有任何理智"的方法可以做到这一点?

解决方案

您可以使用 enumeratenext生成器表达式,如果s中没有字符出现则获取第一个匹配或返回None:

s = "Hello world!"st = {"!"," "}ind = next((i for i, ch in enumerate(s) if ch in st),None)打印(索引)

如果没有匹配项,您可以将接下来要传递的任何值作为默认返回值传递.

如果你想使用一个函数并引发一个 ValueError:

def first_index(s, characters):st = 设置(字符)ind = next((i for i, ch in enumerate(s) if ch in st), None)如果 ind 不是 None:返回工业引发值错误

对于较小的输入,使用集合不会有太大区别,但对于大字符串,它会更有效.

一些时间:

在字符串中,字符集的最后一个字符:

In [40]: s = "Hello world!"* 100在 [41] 中:字符串 = s在 [42] 中:%%timeitst = {"x","y","!"}next((i for i, ch in enumerate(s) if ch in st), None)....:1000000 个循环,最好的 3 个:每个循环 1.71 µs在 [43] 中:%%timeit特价 = ['x', 'y', '!']min(map(lambda x: (string.index(x) if (x in string) else len(string)), specials))....:100000 个循环,最好的 3 个:每个循环 2.64 µs

不在字符串中,更大的字符集:

在 [44]: %%timeitst = {"u","v","w","x","y","z"}next((i for i, ch in enumerate(s) if ch in st), None)....:1000000 个循环,最好的 3 个:每个循环 1.49 µs在 [45] 中:%%timeitspecials = ["u","v","w","x","y","z"]min(map(lambda x: (string.index(x) if (x in string) else len(string)), specials))....:100000 个循环,最好的 3 个:每个循环 5.48 µs

在字符串中字符集的第一个字符:

在 [47]: %%timeit特价 = ['H', 'y', '!']min(map(lambda x: (string.index(x) if (x in string) else len(string)), specials))....:100000 个循环,最好的 3 个:每个循环 2.02 µs在 [48] 中:%%timeitst = {"H","y","!"}next((i for i, ch in enumerate(s) if ch in st), None)....:1000000 个循环,最好的 3 个:每个循环 903 ns

I'd like to find the index of the first occurrence of any "special" character in a string, like so:

>>> "Hello world!".index([' ', '!'])
5

…except that's not valid Python syntax. Of course, I can write a function that emulates this behavior:

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)

I could also use regular expressions, but both solutions seem to be a bit overkill. Is there any "sane" way to do this in Python?

解决方案

You can use enumerate and next with a generator expression, getting the first match or returning None if no character appears in s:

s = "Hello world!"

st = {"!"," "}
ind = next((i for i, ch  in enumerate(s) if ch in st),None)
print(ind)

You can pass any value you want to next as a default return value if there is no match.

If you want to use a function and raise a 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

For smaller inputs using a set won't make much if any difference but for large strings it will be a more efficient.

Some timings:

In the string, last character of character set:

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

Not in the string, larger character set:

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 string an very first character of character set:

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

这篇关于如何找到字符串中任何一组字符的第一个索引的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆