从字符串列表计算-Python
我有一个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,那么这可能吗?或者我应该改变
['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
将其扩展到包含更多运算符(例如指数运算符“^”和多位数整数)的完整字符串计算器将非常容易。圆括号、浮点数和函数可能需要做一些工作,但也不难。在我看来,每个程序员一生中都应该尝试一次。它只是+和-而已吗?