首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从字符串列表计算- Python

从字符串列表计算- Python
EN

Stack Overflow用户
提问于 2013-07-22 07:05:33
回答 3查看 500关注 0票数 0

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

代码语言:javascript
复制
['9-8+7', '7-8-6']

我想要做的是得到每个字符串的值,这样循环遍历字符串,一个数组将看到9-8+7,并将追加8,7-8-6将追加-7。我不能将带操作数的字符串转换为int,所以这是可能的吗?或者我应该改变算法,而不是为每个随机输出创建一个字符串,而是立即计算它的值?

提前谢谢你。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-07-22 07:10:26

您可以对列表项执行eval,但这是一个潜在的安全漏洞,只有在您完全信任源代码的情况下才应该使用。

代码语言:javascript
复制
>>> map(eval, ['9-8+7', '7-8-6'])
[8, -7]

如果您控制生成字符串的代码,则直接计算值听起来是一种更好的方法(更安全,也可能更快)。

票数 4
EN

Stack Overflow用户

发布于 2013-07-22 07:54:16

正如Fredrik所指出的,您可以在Python中执行eval。我想我应该添加一种更通用的方法,它可以在任何语言中工作,并且可能会为那些还没有看到简单解析器实际应用的人提供一些帮助。

您正在描述一种语言,其正式定义类似于:

代码语言:javascript
复制
expr := sum
sum := prod [("+" | "-") prod]...
prod := digit [("*" | "/") digit]...
digit := '0'..'9'

这个语法(我不会费心去做正确的EBNF)接受这些字符串:"3“、"4*5/2”和"8*3+9",等等。

这给了我们一个如何解析它的线索,求值就是在我们前进的过程中积累结果。下面是Python 2的工作代码。请注意代码与语法的关系有多紧密。

代码语言:javascript
复制
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]

下面是一个示例运行:

代码语言:javascript
复制
$ 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

将其扩展到具有更多运算符的完整字符串计算器是非常容易的,例如指数运算符'^‘和多位整数。圆括号、浮点数和函数可能有点麻烦,但也不难。在我看来,每个程序员都应该在他们的生活中尝试一次。

票数 2
EN

Stack Overflow用户

发布于 2013-07-22 07:26:22

当然,这取决于您的表达式的行为和限制程度。

因为减法是带负数的加法,所以你可以把减法写成带负数的加法。在+上吐痰以查找术语。然后将求和项解析为整数,并对它们求和。对每个表达式执行此操作。

代码语言:javascript
复制
[sum(map(int,l.replace('-', '+-').split('+'))) for l in ['9-8+7','7-8-6']]
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17777856

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档