2011-06-12 3 views
4

У меня есть два генератора. Первый генератор иногда нужно вызвать второй генератор и выход обратно значения он получил от туда:пакет/распаковать генератор

def a(): 
    for _b in b(): 
     yield _b 

def b(): 
    yield 1 
    yield 2 

for _a in a(): 
    print _a 

Есть ли более элегантный способ сделать это:

for _b in b(): 
    yield _b 

Я попытался это:

yield *b() 

Но, конечно, это не работает. У меня Python 2.6.

+1

Вы на самом деле пытаетесь возвратить все из 'b()' сразу? –

+0

Да, я пытаюсь в() получить все значения, которые я получаю от b(). – warvariuc

+0

'a()' является функцией обратного вызова scrapy spider (http://doc.scrapy.org/topics/spiders.html#topics-spiders) – warvariuc

ответ

6

Я думаю, вы имеете в виду PEP380. Это available from Python 3.3. Это выглядит так:

yield from b() 

В Python2 нет специального синтаксиса. Вы просто используете for-loop.

Функция a в вашем вопросе на самом деле абсолютно бесполезна. Вы можете просто использовать b в своем месте.

+0

В реальном коде (scrapy spider method) 'a' дает некоторые свои значения. я думаю, если есть PEP, это означает, что проблема известна, и на данный момент нет элегантного решения. – warvariuc

2

Ну, на этом простом примере вы могли бы просто написать a = b или a = lambda: b. Но если a добавляет элементы своей собственной, вы можете использовать itertools.chain:

import itertools 
def a(): 
    return itertools.chain(['a-value'], b()) 

Имейте в виду, что, хотя этот вариант может быть короче, for: yield является вполне интуитивно (и, следовательно, легко понять) модель.

+1

спасибо за альтернативу, хотя и не изящный – warvariuc

3

Вы можете использовать выражение генератора. Он примерно такой же сжатый, как и цикл, плюс указывает, что ваш код в основном предназначен для создания возвращаемого значения вместо побочного эффекта.

def a(): 
    return (_b for _b in b()) 

Как сказал phihag, вероятно, можно просто написать a = b, если ваш код действительно как в этом примере, так как и б вернуть ту же последовательность.

+1

'a', который вы написали, является встроенным именем' iter' –

+0

'return (_b for _b in b())' более легко (и эффективно) записывается как 'return b()', и он не работает, если 'a' является самой функцией генератора (как задается вопрос). –

+0

да, это не работает, так как оно дает значение типа warvariuc

Смежные вопросы