Python3 中的惰性评估
lazy evaluation in Python3
假设我有一个有副作用的函数(在这个例子中,副作用是打印了一些东西)。是否有任何版本的 any() 或可迭代列表的任何构造在找到 True 结果后不会触发副作用?
例如,假设这个函数:
def a(x):
print("A function got: " + str(x))
return x == 2
有人可能希望这个电话会成功。当然不是:
any([
a(i) for i in range(5)
])
打印:
A function got: 0
A function got: 1
A function got: 2
A function got: 3
A function got: 4
但我希望它打印这个:
A function got: 0
A function got: 1
A function got: 2
为什么? Range 是一个可迭代的,列表理解产生一个可迭代的,我希望 Python 将它们链接在一起并在 any() 函数停止使用时立即停止执行整个事情,一旦它应该这样做达到第一个 True.
我误会了什么?如果有的话,哪个版本会以这种方式运行?
您可以通过在列表理解中添加条件来使用以下代码
def a(x):
print("A function got: " + str(x))
any([
a(i) for i in range(5) if i<3
])
无论何时使用列表,都会计算所有值。获得懒惰评估的唯一方法是将其保留为迭代器。您可以使用生成器理解来做到这一点:
any(a(i) for i in range(5))
明确地说,使用括号与 any(list(a(i) for i in range(5)))
相同。
您也可以简单地 运行 循环和 break
循环:
for i in range(5):
if a(i):
break
所以
def my_any(func, it):
for i in it:
if func(i):
break
my_any(a, range(5))
另一个有效的解决方案如下,首先从 itertool takewhile 导入,然后,
l=list(takewhile(lambda x:a(x) is False, range(5)))
假设我有一个有副作用的函数(在这个例子中,副作用是打印了一些东西)。是否有任何版本的 any() 或可迭代列表的任何构造在找到 True 结果后不会触发副作用?
例如,假设这个函数:
def a(x):
print("A function got: " + str(x))
return x == 2
有人可能希望这个电话会成功。当然不是:
any([
a(i) for i in range(5)
])
打印:
A function got: 0
A function got: 1
A function got: 2
A function got: 3
A function got: 4
但我希望它打印这个:
A function got: 0
A function got: 1
A function got: 2
为什么? Range 是一个可迭代的,列表理解产生一个可迭代的,我希望 Python 将它们链接在一起并在 any() 函数停止使用时立即停止执行整个事情,一旦它应该这样做达到第一个 True.
我误会了什么?如果有的话,哪个版本会以这种方式运行?
您可以通过在列表理解中添加条件来使用以下代码
def a(x):
print("A function got: " + str(x))
any([
a(i) for i in range(5) if i<3
])
无论何时使用列表,都会计算所有值。获得懒惰评估的唯一方法是将其保留为迭代器。您可以使用生成器理解来做到这一点:
any(a(i) for i in range(5))
明确地说,使用括号与 any(list(a(i) for i in range(5)))
相同。
您也可以简单地 运行 循环和 break
循环:
for i in range(5):
if a(i):
break
所以
def my_any(func, it):
for i in it:
if func(i):
break
my_any(a, range(5))
另一个有效的解决方案如下,首先从 itertool takewhile 导入,然后,
l=list(takewhile(lambda x:a(x) is False, range(5)))