Python 如何检测字符串中的4个字符中的任何一个,然后返回它们的索引?

Python 如何检测字符串中的4个字符中的任何一个,然后返回它们的索引?,python,Python,假设我只查找一个特定字符,我会理解如何执行此操作,但在本例中,我查找的是4个运算符“+”、“-”、“*”、“/”中的任意一个。如果传递的字符串txt中没有运算符,则函数返回-1,否则返回最左边运算符的位置。所以我认为find()在这里是最优的 到目前为止,我所拥有的: def findNextOpr(txt): # txt must be a nonempty string. if len(txt) <= 0 or not isinstance(txt, str):

假设我只查找一个特定字符,我会理解如何执行此操作,但在本例中,我查找的是4个运算符“+”、“-”、“*”、“/”中的任意一个。如果传递的字符串txt中没有运算符,则函数返回-1,否则返回最左边运算符的位置。所以我认为find()在这里是最优的

到目前为止,我所拥有的:

def findNextOpr(txt):
# txt must be a nonempty string.
    if len(txt) <= 0 or not isinstance(txt, str):
        print("type error: findNextOpr")
        return "type error: findNextOpr"
    if '+' in txt:
        return txt.find('+')
    elif '-' in txt:
        return txt.find('-')
    else
        return -1
def findnextropr(txt):
#txt必须是非空字符串。

如果len(txt)您当前的方法不是很有效,因为您将对
txt
进行多次迭代,每个操作符迭代2次(
in
find()

您可以使用
index()
而不是
find()
,只需忽略
ValueError
异常,例如:

def findNextOpr(txt):
    for o in '+-*/':
        try:
            return txt.index(o)
        except ValueError:
            pass
    return -1
您可以通过对
txt
进行一次遍历(
enumerate()
),并在找到字符时返回,例如:

def findNextOpr(txt):
    for i, c in enumerate(txt):
        if c in '+-*/':
            return i
    return -1
注意:如果需要所有运算符,可以将
return
更改为
yield
,然后在生成器上迭代,例如:

def findNextOpr(txt):
    for i, c in enumerate(txt):
        if c in '+-*/':
            yield i

In []:
for op in findNextOpr('1+2-3+4'):
    print(op)

Out[]:
1
3
5

您当前的方法不是很有效,因为您将对每个操作符迭代多次
txt
,每次迭代2(
in
find()

您可以使用
index()
而不是
find()
,只需忽略
ValueError
异常,例如:

def findNextOpr(txt):
    for o in '+-*/':
        try:
            return txt.index(o)
        except ValueError:
            pass
    return -1
您可以通过对
txt
进行一次遍历(
enumerate()
),并在找到字符时返回,例如:

def findNextOpr(txt):
    for i, c in enumerate(txt):
        if c in '+-*/':
            return i
    return -1
注意:如果需要所有运算符,可以将
return
更改为
yield
,然后在生成器上迭代,例如:

def findNextOpr(txt):
    for i, c in enumerate(txt):
        if c in '+-*/':
            yield i

In []:
for op in findNextOpr('1+2-3+4'):
    print(op)

Out[]:
1
3
5

您可以稍微改进您的代码,因为您可以多次查看字符串'+'实际上就像
txt.find('+')
一样搜索字符串。因此,您可以轻松地将它们组合在一起,以避免在其中搜索两次:

pos = txt.find('+')
if pos >= 0:
    return pos
但这仍然会给您带来一个问题,即如果您要查找的第一个运算符包含在字符串中的任何位置,那么它将返回该运算符。因此,实际上没有得到字符串中任何运算符的第一个位置

因此,您要做的是分别查找所有运算符,然后返回最小的非负数,因为这是字符串中任何运算符的第一次出现:

plusPos = txt.find('+')
minusPos = txt.find('-')
multPos = txt.find('*')
divPos = txt.find('/')

return min(pos for pos in (plusPos, minusPos, multPos, divPos) if pos >= 0)

您可以稍微改进您的代码,因为您可以多次查看字符串'+'实际上就像
txt.find('+')
一样搜索字符串。因此,您可以轻松地将它们组合在一起,以避免在其中搜索两次:

pos = txt.find('+')
if pos >= 0:
    return pos
但这仍然会给您带来一个问题,即如果您要查找的第一个运算符包含在字符串中的任何位置,那么它将返回该运算符。因此,实际上没有得到字符串中任何运算符的第一个位置

因此,您要做的是分别查找所有运算符,然后返回最小的非负数,因为这是字符串中任何运算符的第一次出现:

plusPos = txt.find('+')
minusPos = txt.find('-')
multPos = txt.find('*')
divPos = txt.find('/')

return min(pos for pos in (plusPos, minusPos, multPos, divPos) if pos >= 0)

首先,您不应该打印或返回错误消息;你应该提出例外情况
TypeError
ValueError
在这里是合适的。(不够长的字符串是后者,而不是前者。)

其次,您可以使用列表理解简单地查找字符串中所有运算符的位置,排除-1的结果,并使用
min()
返回位置中的最低值


我添加了一个
start
参数,可用于查找下一个运算符:只需传入上一个找到的运算符的索引,再加上1。

首先,您不应该打印或返回错误消息;你应该提出例外情况
TypeError
ValueError
在这里是合适的。(不够长的字符串是后者,而不是前者。)

其次,您可以使用列表理解简单地查找字符串中所有运算符的位置,排除-1的结果,并使用
min()
返回位置中的最低值


我添加了一个
start
参数,可用于查找下一个运算符:只需传入上一个找到的运算符的索引,再加上1。

假设您的意思是
range(len(txt))
,尽管
enumerate()
可能是一种更规范的方法。@AChampion我做到了,谢谢!是的,enumerate也很有效,我很感谢你花时间研究几个场景。最后一个提到使用循环的例子说明了一个事实,即可能存在多个操作符实例,对吗?例如,txt是“4+5+6*2”。这里有2个'+'运算符。因为只要“+”是所提到字符串的一部分,循环就会继续。正如我在AChampion的问题中提到的,循环1次而不是4次所节省的成本实际上可能不会超过Python中循环和重复索引与C中循环的成本(或者甚至可以调用类似于
memchr
的东西,甚至可能比这更优化…),尤其是在CPython中。从更干净、可读性更强的意义上讲,它肯定更好,但它可能不会更快,您的答案表明它更快。@MJames28不确定我是否理解您的意思。对于字符串
4+5+6*2
,函数将返回
2
,因为在索引2中,字符串中有第一个运算符。循环将在此之后停止。假设您的意思是
range(len(txt))
,尽管
enumerate()
可能是一种更为规范的方法。@AChampion我做到了,谢谢!是的,enumerate也很好用。我感谢您花时间研究几个场景。最后一个提到使用循环的例子说明了以下事实: