Python 如何检测字符串中的4个字符中的任何一个,然后返回它们的索引?
假设我只查找一个特定字符,我会理解如何执行此操作,但在本例中,我查找的是4个运算符“+”、“-”、“*”、“/”中的任意一个。如果传递的字符串txt中没有运算符,则函数返回-1,否则返回最左边运算符的位置。所以我认为find()在这里是最优的 到目前为止,我所拥有的: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):
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也很好用。我感谢您花时间研究几个场景。最后一个提到使用循环的例子说明了以下事实: