我正在寻找一种很好的方法来顺序合并两个itertools运算符。作为一个例子,假设我们想从一个生成器序列中选择小于阈值的数字,在超过阈值之后。对于12000的阈值,这些将对应于it.takewhile(lambda x: x<12000)
和it.takewhile(lambda x: x>=12000)
:
# Set up an example generator:
def lcg(a=75,c=74,m=2**16+1,x0 = 1):
xn = x0
yield xn
while True:
xn = (a*xn+c) % m
yield xn
# First 20 elements:
list(it.islice(lcg(), 20))
[1, # <- start sequence, start it.takewhile(lambda x: x<12000)
149,
11249, # <- last element of it.takewhile(lambda x: x<12000)
57305, # <- start it.takewhile(lambda x: x>=12000) here
38044,
35283,
24819,
26463,
18689,
25472, # <- last element of it.takewhile(lambda x: x>=12000); end of sequence
9901,
21742,
57836,
12332,
7456,
34978,
1944,
14800,
61482,
23634]
是否有方法选择大于12000的序列,包括小于12000的初始值,即所需输出为:
[1, 149, 11249, 57305, 38044, 35283, 24819, 26463, 18689, 25472]
这对于两个for循环来说很简单,但是我正在寻找一种itertools-type的方法(也许是一行程序?)来组合这两个操作符,而不需要重置lcg
生成器。
1条答案
按热度按时间kb5ga3dv1#
针对现有
itertools
库的问题编写一行程序的一种方法是使用具有{0}
作为默认值的标志变量来指示要使用哪个 predicate 。(x < 12000
)是有效的,如果第一个 predicate 失败,弹出集合,使其计算为falsey以使用第二个 predicate (x >= 12000
)进行评估。通过从集合中弹出0
,当第一个 predicate 失败时,它还允许表达式在同一次迭代中回退到第二个 predicate :请注意,在这种情况下,使用可变对象作为参数的默认值是安全的,因为
lambda
在每次计算时都会创建一个新的函数对象沿着可变对象的新示例。演示:https://replit.com/@blhsing/VirtualGuiltyRatio