【问题标题】:How to make a string interpreted as a condition with Python?如何使用 Python 将字符串解释为条件?
【发布时间】:2018-05-22 10:19:22
【问题描述】:

我需要使用下面的语法来过滤列表operations

a = [ope for ope in operations if ope[0] == 1]

if 语句条件是可变的,可能包含多个条件:

a = [ope for ope in operations if ope[0] == 1 and ope[1] == "test"]

我使用一个函数来构建条件并将其作为字符串返回:

>>>> c = makeCondition(**{"id": 1, "title": 'test'})
>>>> c
"ope[0] == 1 and ope[1] == 'test'"

有没有办法将c 变量集成到列表过滤中?像这样(当然,c 变量在下面的示例中被评估为字符串):

 a = [ope for ope in operations if c]

感谢您的帮助!

【问题讨论】:

  • 你试过a = [... if eval(c)]吗?
  • 为什么将条件构建为字符串?将其设为函数或 lambda 会更有意义。
  • a = [... if eval(c)] 确实有效,谢谢@Chris!考虑将您的评论添加为答案,以便我接受。 @tripleee:我不明白你的意思。你能用一个基本的语法例子告诉我更多吗?
  • 你可以做conditions[0] = lambda ope : ope[0] == 1等等。将所有条件作为内部 lambda 函数填写一个列表,然后在列表推导中,选择您要与 a = [ope for ope in operations if conditions[0](ope)] 一起使用的一个条件。
  • 让你的函数返回逻辑结果而不是字符串。然后你可以在你的测试中使用它。不要生成大量代码然后使用evel——几乎永远...

标签: python python-3.x if-statement conditional-statements


【解决方案1】:

eval 被认为是unsafe,通常会被避免。

您可以将[filter][1] 与函数一起使用。为此,您应该将测试条件放在一个函数中。

这是一个创建 1 到 100 之间的数字列表的示例,这些数字是 3 和 7 的倍数

def mult3(n):
    return n % 3 == 0

def mult7(n):
    return n % 7 == 0

def mult3_and_7(n):
    return mult3(n) and mult7(n)

list(filter(mult3_and_7, range(1, 101)))

更简洁的方法是使用lambdas

list(filter(lambda n: (n % 3 == 0) and (n % 7 == 0), range(1, 101))

很酷的是你可以像这样链接过滤器:

list(filter(lambda n: n % 3 == 0, filter(lambda n: n % 7 == 0, range(1, 101))))

他们都给[21, 42, 63, 84]

这种方法应该可以帮助您清楚地链接多个条件。

【讨论】:

  • 这有帮助,谢谢!但就我而言,我需要从作为 **kwargs 传递的字典中收集与每个键关联的值,而不仅仅是 True 或 False 值。
  • 在您的情况下,makeCondition 似乎是用ope 硬编码的,这意味着它可能会被重构为makeCondition(some_list, **kwargs) -> bool 之类的东西。测试不是返回字符串,而是在makeCondition 中进行。这样,你可以很容易地做到list(filter(makeCondition, ope))
  • 我已经发表了另一篇与该主题相关的帖子:stackoverflow.com/q/47769705/2508539。再次感谢!
【解决方案2】:

如评论所述,如果您想将字符串更改为表达式,可以使用eval(string)

【讨论】:

  • 使用 eval 几乎总是错误的解决方案。这里的问题当然可以使用 lambdas 来解决
猜你喜欢
  • 2014-08-15
  • 2020-09-14
  • 2019-05-18
  • 1970-01-01
  • 2016-05-22
  • 2020-12-15
  • 2013-05-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多