我有以下代码:
def evAnd(v, *predicates):
satisfied=True
for f in predicates:
if not f(v):
satisfied=False
# log: f,v->False in a map and other side effects
else:
# log: f,v->True in a map and other side effects
return satisfied
def evOr(v, *predicates):
satisfied=False
for f in predicates:
if f(v):
satisfied=True
# log: f,v->True in a map and other side effects
else:
# log: f,v->False in a map and other side effects
return satisfied
将上述内容统一到一个函数中的 Pythonic 方法是什么? (因为放置日志消息的地方有相当多的副作用代码)请注意副作用的存在以及需要评估所有谓词的结果,而不会使 any 短路和 all
基于已接受答案的解决方案
所以,这是我最终根据接受的答案所做的:
def adorn(predicate):
def rv(v):
rvi = predicate(v)
if rvi:
print "%s is satisfied for value %d" % (predicate.__name__, v)
# any other side effects
else:
print "%s is not satisfied for value %d" % (predicate.__name__, v)
# any other side effects
return rvi
return rv
def my_all(n, predicates):
return reduce(operator.and_, map( lambda x : x(n), map(adorn, predicates)), True)
def my_any(n, predicates):
return reduce(operator.or_, map( lambda x : x(n) , map(adorn, predicates)), False)
它可以通过以下方式进行测试:
def even(n):
return n%2==0
def odd(n):
return n%2!=0
print my_all(3, [even, odd])
print my_any(4, [even, odd])
最佳答案
一般来说,如果你将生成器表达式传递给 any
或 all
它会被短路,但如果你将它设为 LC 并将其传递给这两个构建-ins,短路是不可能的,你会得到你想要追求的效果
以下演示是不言自明的,可以根据您的问题进行调整
>>> count = 0
>>> def foo(n):
global count
count += 1
return n%2
>>> any(foo(n) for n in range(10))
True
>>> count
2
>>> count = 0
>>> any([foo(n) for n in range(10)])
True
>>> count
10
根据 Blender 的建议,它可能会创建一个应该被丢弃的列表。更面向生成器的解决方案如下
研究此问题的另一种方法(至少对于生成器而言)是,如果被 any
或 all
短路,您希望消耗剩余的可迭代对象。你可以很容易地这样做,部分借用 consume itertools recipe
>>> count
0
>>> it = (foo(n) for n in range(10))
>>> any(it)
True
>>> collections.deque(it, maxlen = 0)
deque([], maxlen=0)
>>> count
10
这里有两个版本的 any 和 all 不会短路。随意给这些函数起一个有意义的名字(我真的很糟糕)
>>> def all_noss(expr):
it = iter(expr)
result = any(it)
collections.deque(it, maxlen = 0)
return result
>>> def any_noss(expr):
it = iter(expr)
result = any(it)
collections.deque(it, maxlen = 0)
return result
关于Python any(iterable) 和 all(iterable) 没有短路和副作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14642179/