生成器的代理方法

时间:2014-02-11 14:49:05

标签: python generator

我有一个生成方法next_item(data)

我把它称为循环:

for count, item in enumerate(next_item(data)):
    # do something here

但是现在我想扩展我的程序 - 根据输入将next_item方法分成两个方法。

所以next_item()看起来像这样:

if ...: # some condition here
  yield(next1(data)) # or return(next1(data)) ??
else:
  yield(next2(data))

但是返回不起作用("SyntaxError: 'return' with argument inside generator")yield显然导致项目是生成器而不是此生成器的项目。

所以我将不得不重构调用脚本,但我想知道是否有办法编写这样的代理生成器。

1 个答案:

答案 0 :(得分:4)

从您的错误消息中,听起来像您尝试过类似的内容:

if ...: # some condition here
  return (next1(data))
else:
  yield (next2(data))

Python不会接受一个既产生又返回的函数。如果您希望它能够工作,您需要将两个收益率更改为回报。

以下是在两个生成器之间选择的函数示例:

def squares():
    i = 0
    while True:
        yield i * i
        i += 1

def evens():
    i = 0
    while True:
        yield i*2
        i += 1

def next_item(switch):
    if switch == 0:
        return squares()
    else:
        return evens()

print "printing squares..."
for idx, item in enumerate(next_item(0)):
    print idx, item
    if idx > 10: break

print "printing evens..."
for idx, item in enumerate(next_item(1)):
    print idx, item
    if idx > 10: break

结果:

printing squares...
0 0
1 1
2 4
3 9
4 16
5 25
6 36
7 49
8 64
9 81
10 100
11 121
printing evens...
0 0
1 2
2 4
3 6
4 8
5 10
6 12
7 14
8 16
9 18
10 20
11 22

如果您愿意,也可以将next_item作为生成器:

def next_item(switch):
    if switch == 0:
        for item in squares(): yield item
    else:
        for item in evens(): yield item

或者可能:

def next_item(switch):
    for item in squares() if switch == 0 else evens():
        yield item

如果您使用的是3.X,则可以使用yield from

def next_item(switch):
    yield from squares() if switch == 0 else evens()