从字符串列表计算-Python

从字符串列表计算-Python,python,string,int,Python,String,Int,我有一个python公式,它将操作数随机放置在数字之间。例如,列表可以如下所示: ['9-8+7', '7-8-6'] expr := sum sum := prod [("+" | "-") prod]... prod := digit [("*" | "/") digit]... digit := '0'..'9' 我想做的是获取每个字符串的值,这样在字符串中循环,数组将看到9-8+7,并将附加8,7-8-6将附加-7。我无法将带有操作数的字符串转换为int,那么这可能吗?或者我应该改变

我有一个python公式,它将操作数随机放置在数字之间。例如,列表可以如下所示:

['9-8+7', '7-8-6']
expr := sum
sum := prod [("+" | "-") prod]...
prod := digit [("*" | "/") digit]...
digit := '0'..'9'
我想做的是获取每个字符串的值,这样在字符串中循环,数组将看到9-8+7,并将附加8,7-8-6将附加-7。我无法将带有操作数的字符串转换为int,那么这可能吗?或者我应该改变算法,这样就不用为每个随机输出创建一个字符串,而是立即计算它的值

提前感谢。

您可以对列表项进行评估,但这是一个潜在的安全漏洞,只有在完全信任源的情况下才应使用

>>> map(eval, ['9-8+7', '7-8-6'])
[8, -7]

如果您控制生成字符串的代码,那么直接计算值似乎是一种更安全、可能更快的更好方法。

这当然取决于表达式的性能和限制程度

由于减法是负数加法,因此可以将减法写成负数加法。向+吐口水以查找术语。然后将求和的项解析为整数,并求和。对每个表达式都这样做

[sum(map(int,l.replace('-', '+-').split('+'))) for l in ['9-8+7','7-8-6']]

正如Fredrik指出的,您可以用Python进行eval。我想我应该添加一种在任何语言中都适用的更通用的方法,并可能为那些还没有看到它们的人提供一些简单的解析器

您正在描述一种语言,其形式定义如下:

['9-8+7', '7-8-6']
expr := sum
sum := prod [("+" | "-") prod]...
prod := digit [("*" | "/") digit]...
digit := '0'..'9'
我不想费心修改EBNF的语法接受以下字符串:3、4*5/2和8*3+9,依此类推

这为我们提供了一条如何解析它的线索,而评估只不过是不断积累结果。下面是正在运行的Python2代码。请注意代码是如何严格遵循语法的

class ParseFail(Exception):
    pass

def eval_expr(str):
    value, pos = eval_sum(str, 0)
    return value

def eval_sum(str, pos):
    value, pos = eval_product(str, pos)
    accum = value
    while pos != len(str):
        op = str[pos]
        if not str[pos] in ['+', '-']:
            raise ParseFail("Unexpected symbol at position "
                            "{pos} of {str}".format(str=str, pos=pos))
        value, pos = eval_product(str, pos + 1)
        if op == '+':
            accum += value
        else:
            accum -= value
    return accum, pos

def eval_product(str, pos):
    value, pos = eval_digit(str, pos)
    accum = value
    while pos != len(str):
        op = str[pos]
        if not str[pos] in ['*', '/']:
            return accum, pos
        value, pos = eval_digit(str, pos + 1)
        if op == '*':
            accum *= value
        else:
            accum /= value
    return accum, pos

def eval_digit(str, pos):
    if not str[pos].isdigit():
        raise ParseFail("Unexpected symbol at position "
                        "{pos} of {str}".format(str=str, pos=pos))
    return int(str[pos]), pos + 1

try:
    print "3 ->", eval_expr("3")
    print "3*4 ->", eval_expr("3*4")
    print "2+3*4-5 ->", eval_expr("2+3*4-5")

    # Should raise ParseFail
    print "2+3*4^2-5 ->", eval_expr("2+3*4^2-5")
except ParseFail as err:
    print
    print err.args[0]
下面是一个运行示例:

$ python simple_expr.py
3 -> 3
3*4 -> 12
2+3*4-5 -> 9
2+3*4^2-5 ->
Unexpected symbol at position 5 of 2+3*4^2-5
将其扩展到包含更多运算符(例如指数运算符“^”和多位数整数)的完整字符串计算器将非常容易。圆括号、浮点数和函数可能需要做一些工作,但也不难。在我看来,每个程序员一生中都应该尝试一次。

它只是+和-而已吗?