我想了解如何基于条件迭代生成器,并且在不满足条件时仅返回当前状态而不调用next()。
例如,给定从1到n的重复一系列整数,如何创建从0开始的冻结指数,直到系列中的下一个值满足条件为止?
我的尝试是:
def generator():
number = 0
while True:
number +=1
yield number
gen = generator()
start = gen.next()
def f(x):
if x>5:
current = gen.next()
return current
pd.Series(list(itertools.chain(np.arange(10),np.arange(10)))).apply(f)
返回
0 NaN
1 NaN
2 NaN
3 NaN
4 NaN
5 NaN
6 2.0
7 3.0
8 4.0
9 5.0
10 NaN
11 NaN
12 NaN
13 NaN
14 NaN
15 NaN
16 6.0
17 7.0
18 8.0
19 9.0
但输出应为
0 0.0
1 0.0
2 0.0
3 0.0
4 0.0
5 0.0
6 1.0
7 2.0
8 3.0
9 4.0
10 5.0
11 5.0
12 5.0
13 5.0
14 5.0
15 5.0
16 6.0
17 7.0
18 8.0
19 9.0
但是,像current = start这样的frozenIndex中的else条件将始终返回保存的第一个生成器值。
答案 0 :(得分:1)
您可以通过.send
方法将数据发送到生成器来完成此类操作。这是一个(相对)简单的例子。
def conditional_counter():
''' An infinite counter that freezes on the last value
if the sent-in value is False-ish
'''
yield
value = 0
while True:
condition = yield value
if condition:
value += 1
counter = conditional_counter()
counter.send(None)
for s in 'abcdefghijklmnop':
val = counter.send(s == 'c' or s >= 'h')
print(s, val)
<强>输出强>
a 0
b 0
c 1
d 1
e 1
f 1
g 1
h 2
i 3
j 4
k 5
l 6
m 7
n 8
o 9
p 10
第一次调用.send()
必须传递None
作为arg,否则你会得到
TypeError: can't send non-None value to a just-started generator
所以我们用
来处理counter.send(None)
和生成器中的第一个yield
语句。 FWIW,&#34;裸体&#34; yield
会产生None
,就像裸return
返回None
一样。
这是一个更复杂的生成器,可以通过任何迭代传递。
def conditional_counter(iterable):
''' An iterator that freezes on the last value
if the sent-in value is False-ish,
or if the iterable runs out of items.
'''
it = iter(iterable)
yield
value = next(it)
while True:
condition = yield value
if condition:
try:
value = next(it)
except StopIteration:
pass
counter = conditional_counter(range(9))
counter.send(None)
for s in 'abcdefghijklmnop':
val = counter.send(s == 'c' or s >= 'h')
print(s, val)
<强>输出强>
a 0
b 0
c 1
d 1
e 1
f 1
g 1
h 2
i 3
j 4
k 5
l 6
m 7
n 8
o 8
p 8
答案 1 :(得分:0)
您可以使用 0.0
初始化flag_val
flag_val = 0.0
def frozenIndex(x):
if x>5:
current = gen.next()
flag_val = current
else:
current = flag_val
return current
这应解决你想要做的事情,但你不能在收益上前后移动。