【发布时间】:2017-07-14 14:53:59
【问题描述】:
通常会出现需要无限循环直到达到特定条件的情况。例如,如果我想继续收集随机整数,直到找到一个数字 == n,然后我打破。我会这样做:
import random
rlist = []
n = ...
low, high = ..., ...
while True:
num = random.randint(low, high)
if num == n:
break
rlist.append(num)
这很有效,但是很笨重。使用iter 有一个更 Pythonic 的替代方案:
iter(o[, sentinel])
返回一个迭代器对象。第一个论点是 根据第二个的存在,解释非常不同 争论。 [...] 如果第二个论点, sentinel, 是给定的,那么 o 必须是一个可调用的对象。迭代器 在这种情况下 created 将调用 o ,每次调用都没有参数 它的
next()方法;如果返回的值等于哨兵, 将引发 StopIteration,否则将返回该值。
上面的循环可以换成
import random
from functools import partial
f = partial(random.randint, low, high)
rlist = list(iter(f, 10))
要将这一原则扩展到已创建的列表,需要稍作改动。我需要像这样定义一个部分函数:
f = partial(next, iter(x)) # where x is some list I want to keep taking items from until I hit a sentinel
其余部分保持不变,但与 while 循环相比,这种方法的主要警告是我不能应用通用布尔条件。
例如,我不能应用“在遇到大于 1000 的第一个偶数之前生成数字”。
底线是:除了while循环和iter支持回调哨兵之外,还有另一种选择吗?
【问题讨论】:
-
为什么
while循环“笨拙”? -
谁在不解释的情况下投反对票?有课吗?
-
它有点笨重和老式。不过我没有什么反对的。只是想探索其他选择。此外,希望得到否决选民的评论。希望有机会纠正任何错误。