【发布时间】:2011-03-25 06:19:17
【问题描述】:
我写了一个简单的脚本来解决“逻辑谜题”,这是一种来自学校的谜题类型,你被赋予了许多规则,然后必须能够找到诸如“有五个名叫 A 的音乐家, B、C、D、E在音乐会上演奏,一个接一个地演奏……如果A在B之前,D不在最后……谁在什么时候演奏的顺序是什么?”等等
为了评估可能的解决方案,我将每个“规则”编写为一个单独的函数,用于评估可能的解决方案(简单地表示为字符串列表)是否有效,例如
#Fifth slot must be B or D
def rule1(solution):
return solution[4] == 'B' or solution[4] == 'D'
#There must be at least two spots between A and B
def rule2(solution):
returns abs(solution.index('A') - solution.index('B')) >= 2
#etc...
我有兴趣找到 Pythonic 的方法来测试一个可能的解决方案是否通过了所有这些规则,并且能够在第一个失败后停止评估规则。
一开始我写了最简单的东西:
def is_valid(solution):
return rule1(solution) and rule2(solution) and rule3(solution) and ...
但这看起来相当丑陋。我想也许我可以通过列表理解之类的东西让这个阅读更加优雅......
def is_valid(solution)
rules = [rule1, rule2, rule3, rule4, ... ]
return all([r(solution) for f in rules])
...但后来我意识到,由于列表理解是在评估 all() 函数之前生成的,所以这具有根本不会短路的副作用 - 即使第一个规则也会被评估返回False。
所以我的问题是:是否有一种更 Pythonic/功能性的方式能够评估 True/False 表达式列表,并进行短路,而无需写出一长串 @987654328 @?
【问题讨论】:
标签: functional-programming python list-comprehension short-circuiting