是否有Python惯用法来评估带有短路的功能/表达式列表? [英] Is there a Python idiom for evaluating a list of functions/expressions with short-circuiting?

查看:57
本文介绍了是否有Python惯用法来评估带有短路的功能/表达式列表?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了一个简单的脚本来解决逻辑难题",这是学校给出的一些规则的难题,然后必须能够找到问题的解决方案,例如有五位音乐家名叫A, B,C,D和E在一场音乐会中演奏,彼此依次演奏...如果A在B之前,而D不是最后一个……谁在什么时候演奏的顺序是什么?"等

I wrote a simple script to solve a "logic puzzle", the type of puzzle from school where you are given a number of rules and then must be able to find the solution for problems like "There are five musicians named A, B, C, D, and E playing in a concert, each plays one after the other... if A goes before B, and D is not last ... what is the order of who plays when?" etc.

为了评估可能的解决方案,例如,我将每个规则"编写为单独的函数,以评估可能的解决方案(简单地表示为字符串列表)是否有效

To evaluate possible solutions, I wrote each "rule" as a separate function which would evaluate if a possible solution (represented simply as a list of strings) is valid, for example

#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...

我有兴趣寻找一种Python方法来测试可能的解决方案是否通过所有此类规则,并能够在第一个失败后停止评估规则.

I'm interested in finding the Pythonic way to test if a possible solution passes all such rules, with the ability to stop evaluating rules after the first has failed.

起初,我写了最简单的东西:

At first I wrote the simplest possible thing:

def is_valid(solution):
    return rule1(solution) and rule2(solution) and rule3(solution) and ...

但这看起来很丑.我以为我可以用列表理解之类的东西使读起来更优雅一些.

But this seemed rather ugly. I thought perhaps I could make this read a bit more elegant with something like a list comprehension...

def is_valid(solution)
    rules = [rule1, rule2, rule3, rule4, ... ]
    return all([r(solution) for f in rules])

...但是我意识到,由于列表理解是在评估all()函数之前生成的,因此具有完全没有短路的副作用-即使第一个规则都会被评估.返回False.

... but then I realized that since the list comprehension is generated before the all() function is evaluated, that this has the side effect of not being short-circuited at all - every rule will be evaluated even if the first returns False.

所以我的问题是:有没有更多的Pythonic/函数式方法可以评估True/False表达式列表,而又无需短路,而无需写出很长的?

So my question is: is there a more Pythonic/functional way to be able to evaluate a list of True/False expressions, with short-circuiting, without the need to write out a long list of return f1(s) and f2(s) and f3(s) ... ?

推荐答案

使用生成器表达式:

rules = [ rule1, rule2, rule3, rule4, ... ]
rules_generator = ( r( solution ) for r in rules )
return all( rules_generator )

语法糖:您可以省略多余的括号:

Syntactic sugar: you can omit the extra parentheses:

rules = [ rule1, rule2, rule3, rule4, ... ]
return all( r( solution ) for r in rules )

生成器(基本上)是具有.next()方法的对象,该方法以某种可迭代的方式返回下一项.这意味着他们可以做一些有用的事情,例如读取块中的文件而无需将其全部加载到内存中,或者迭代到巨大的整数.您可以透明地使用for循环遍历它们. Python在后台处理它.例如,range是Py3k中的生成器.

A generator is (basically) an object with a .next() method, which returns the next item in some iterable. This means they can do useful things like read a file in chunks without loading it all into memory, or iterate up to huge integers. You can iterate over them with for loops transparently; Python handles it behind-the-scenes. For instance, range is a generator in Py3k.

您可以使用yield语句而不是函数定义中的return来滚动自己的自定义生成器表达式:

You can roll your own custom generator expressions by using the yield statement instead of return in a function definition:

def integers():
    i = 0
    while True:
        yield i

,Python将处理保存函数的状态,依此类推.他们太棒了!

and Python will handle saving the function's state and so on. They're awesome!

这篇关于是否有Python惯用法来评估带有短路的功能/表达式列表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆