【问题标题】:Is there a max length to a python conditional (if) statement?python条件(if)语句是否有最大长度?
【发布时间】:2015-06-24 09:16:47
【问题描述】:

我使用 python 的 (2.7) eval() 函数生成一个条件语句,如下所示:

my_list = ['2 > 1','3 > 2','4 > 3']

if eval('(' + ') or ('.join(my_list) + ')'):
    print 'yes'
else:
    print 'no'

在我的例子中,列表是由代码生成的,my_list 来自一个参数文件,并且列表与条件表达式中的“或”语句相连接。上面的代码打印“是”。

它适用于小列表,但在eval() 语句中的字符数达到一定数量时,我会收到字符串错误。

一些搜索发现这些指向错误的线程:

但它们的最大 eval() 大小比我发现的要大得多。就我而言,我发现问题开始在 1744 到 1803 个字符之间。我试过这段代码,它确实在两个语句之间崩溃了

>>> eval("1.0*"*10000+"1.0")
1.0
>>> eval("1.0*"*100000+"1.0")
# segfault here

所以,这让我回想起这不是 eval(),实际上是 if 语句的最大值。

还有什么方法可以有条件地应用列表中不涉及长字符串和 eval() 函数的规则?

有趣的是,我把 my_list 变大了:

my_list = ['2 > 1']*1000000

代码运行良好...

【问题讨论】:

  • 如果条件列表是由代码生成的,为什么在生成时不立即评估?为什么要转换为字符串?
  • @OliverW。条件来自配置文件。因为它们是“或”陈述,所以我不知道如何一次评估一个。我想我可以有一个布尔标志,它以 False 开头,然后如果“if”语句之一的计算结果为 True,则设置为 True。

标签: python python-2.7 conditional eval conditional-statements


【解决方案1】:

也许我遗漏了一些东西,但似乎:

any(map(eval, my_list))

完全按照您的意愿行事。

from itertools import imap

any(imap(eval, my_list)) # Python 2.

如果第一个元素 eval 为 True(也称为“短路”),这具有 评估列表其余部分的良好效果。这可能是也可能不是您所追求的。

例子:

> any(map(eval, ['2 > 1','3 > 2','4 > 3']))
True

【讨论】:

  • 注意:map 只在 Python 3 中是惰性的。在 2.7 下,可以改用itertools.imap 来达到同样的效果。 (之所以这么说是因为 OP 使用的是 Python 2.7。)
  • 这正是我想要的,包括“短路”。对 eval() 有很多仇恨,但我没有看到其他方式。
  • @philshem:有人讨厌eval,这是有充分理由的,但它的存在也是有充分理由的。如果您的目标是“评估一些 Python 代码”,我会说这是最直接的工具。只需考虑安全隐患以及这是否会给您带来问题。
  • @Carsten Python 3 中的“懒惰”是什么意思?
  • @philshem map 在 python2 中将立即对每个元素执行 map 函数。 python3 中的map 和python2 中的imap 将创建一个可迭代对象,其中仅在消耗元素时才评估映射函数。因此,在非惰性情况下,对所有元素进行评估,在惰性情况下,仅对评估为 true 的第一个元素和之前的元素进行评估。
猜你喜欢
  • 1970-01-01
  • 2020-01-15
  • 2022-11-05
  • 2014-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多