更新时间:2023-11-28 17:29:16
为更好地理解,我们也可以将filter
视为生成器:
For better understanding, we can look at filter
as a generator as well:
def filter(condition, iterable):
for value in iterable: # 1. consume values from `iterable`
if condition(value): # 2. test `condition` for `value`
yield value # 3. yield any valid `value`
换句话说,odd_numbers = filter(_not_divisible(n), odd_numbers)
是包装另一个生成器(_odd_number_generator
)的生成器(filter
).对于每个素数,新的filter
会包裹在现有包装的过滤器周围.查看最初的情况之一,我们有以下设置:
In other words, odd_numbers = filter(_not_divisible(n), odd_numbers)
is a generator (filter
) wrapping another generator (_odd_number_generator
). For every prime number, a new filter
is wrapped around the existing wrapped filters. Looking at one of the initial cases, we have this setup:
odd_numbers = filter(_not_divisible(n=7), # <filter A>
filter(_not_divisible(n=5), # <filter B>
filter(_not_divisible(n=3), # <filter C>
_odd_number_generator() # <odd_numbers @ x=7>
))
现在,如果我们叫next(odd_numbers)
会发生什么?
Now, what happens if we call next(odd_numbers)
?
<filter A>:1
通过调用next(<filter B>)
来获取value
<filter B>:1
通过调用next(<filter C>)
来获取value
<filter C>:1
通过调用next(<odd_numbers @ x=7>)
来获取value
<odd_numbers @ x=7>
将x+=2
递增到x=9
并产生<filter A>:1
fetches a value
by calling next(<filter B>)
<filter B>:1
fetches a value
by calling next(<filter C>)
<filter C>:1
fetches a value
by calling next(<odd_numbers @ x=7>)
<odd_numbers @ x=7>
increments x+=2
to x=9
and yields it<odd_numbers @ x=9>
将x+=2
递增到x=11
并产生<odd_numbers @ x=9>
increments x+=2
to x=11
and yields it重要的部分是_not_divisible(n=3)
不允许值9通过.取而代之的是,<filter C>
中的循环获取另一个值而没有产生<filter B>
和<filter A>
.
The important part is that _not_divisible(n=3)
does not let the value 9 pass. Instead, the loop in <filter C>
fetches another value without yielding to <filter B>
and <filter A>
.
随着_odd_number_generator()
周围包裹着越来越多的filter(_not_divibible(n), ...)
层,还有另外一些层可以执行跳过yield
并请求新的value
"".中间生成器可以在屈服之前消耗几个值的一般原理保持不变.
As more and more filter(_not_divibible(n), ...)
layers are wrapped around _odd_number_generator()
, there are additional layers which do the "skip yield
and request new value
". The general principle, that an intermediate generator can consume several values before yielding, remains the same.