0

假设我只是在寻找一个特定的字符,我会理解如何做到这一点,但在这种情况下,我正在寻找 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

我认为,如果我为其他运算符的“+”和“-”运算符所做的事情,它不适用于一个表达式中该运算符的多个实例。可以在这里合并一个循环吗?

4

3 回答 3

2

您当前的方法不是很有效,因为您将为每个运算符 迭代2 次(和)txt多次。infind()

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

def findNextOpr(txt):
    for o in '+-*/':
        try:
            return txt.index(o)
        except ValueError:
            pass
    return -1

您可以通过enumerate()ing thetxt并在找到字符时返回一次(可能更具可读性)来执行此操作,例如:

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

注意:如果您想要所有运算符,您可以将 更改returnyield,然后遍历生成器,例如:

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
于 2018-06-01T00:42:47.673 回答
1

你可以稍微改进你的代码,因为你一直在看这个字符串很多次。'+' in txt实际上就像搜索字符串一样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)
于 2018-06-01T00:45:34.100 回答
0

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

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

def findNextOpr(text, start=0):
    ops = "+-/*"
    if not isinstance(text, str):
       raise TypeError("text must be a string")
    # "text must not be empty" isn't strictly true: 
    # you'll get a perfectly sensible result for an empty string
    if not text:
       raise ValueError("text must not be empty")
    op_idxs = [pos for pos in (text.find(op, start) for op in ops) if pos > -1]
    return min(op_idxs) if op_idxs else -1

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

于 2018-06-01T00:53:30.823 回答