2014-11-17 8 views
3

나는 다음과 같은 코드가 있습니다발전기 표현식에서 'yield from'이 왜 'None`입니까?

import itertools 
for c in ((yield from bin(n)[2:]) for n in range(10)): 
    print(c) 

출력은 다음과 같습니다

0 
None 
1 
None 
1 
0 
None 
1 
1 
None 

... 등은 왜 None들 나타 납니까을? 내가 대신있는 경우 :

def hmm(): 
for n in range(10): 
    yield from bin(n)[2:] 

for c in hmm(): 
    print(c) 

을 그리고 내가 기대하는 것을 얻을 :

0 
1 
1 
0 
1 
1 

... 등 또한, 같은 결과를 얻을 수있는 발전기 식으로 작성하는 방법이 후자로서?

+0

예제를 무한 루프를 사용하지 않는 것으로 변경하는 것이 좋습니다. 'itertools.count'를'range (10)'로 바꾸지 않습니까? – BrenBarn

+0

[docs] (https://docs.python.org/3/whatsnew/3.3.html) : "또한 하위 생성자는 값을 반환 할 수 있으며 값은 위임 생성자가 사용할 수 있습니다. " – tdelaney

+0

첫 번째 코드에서 python2와 3 특정 구문을 혼합하면 print 문을 제거하고 함수 호출을 수행해야합니다. –

답변

10

yield은 표현식이며 그 값은 발전기에 send으로 전송됩니다. 아무 것도 보내지 않으면 yield의 값은 없음입니다. 귀하의 예에서 yield from은 목록에서 값을 산출하지만 yield from 표현식 자체의 값은 없음입니다. 이는 둘러싸는 발전기 표현식의 각 반복 (즉, 모든 값 range(10))에서 산출됩니다.

def hmm(): 
    for n in range(10): 
     yield (yield from bin(n)[2:]) 

for item in hmm(): 
    print(item) 

참고 여분의 yield :

귀하의 예에 해당합니다.

당신이 발전기 표현에 yield를 사용하려고하면 발전기 표현이 이미 목표 값을 산출하기 때문에 당신은 항상이 문제를 가지고, 그래서 당신이 명시 적으로 yield를 추가하는 경우, 당신은 여분의 표현합니다 (yield 표현) 추가 그 값은 또한 생성기에서 출력됩니다. 즉, (x for x in range(5))과 같은 값은 이미 range(5)의 숫자를 산출합니다. ((yield x) for x in range(5)) 같은 것을하면 숫자 외에 yield 표현식의 값을 얻게됩니다.

내가 아는 한, 제너레이터 이해를 사용하여 추가 Nones없이 간단한 yield from 동작을 얻을 수있는 방법이 없습니다. 귀하의 경우, 나는 itertools.chain.from_iterable를 사용하여 당신은 당신이 원하는 것을 얻을 수 있다고 생각 :

for c in itertools.chain.from_iterable(bin(n)[2:] for n in range(10)): 
    print(c) 

(편집 : 난 당신이 중첩 된 for 절을 사용하여 발전기 이해의 yield from 동작을 얻을 수 있습니다 깨달았다. x for n in range(10) for x in bin(n)[2:]을 그러나, 나는 돈 이 코드는 itertools.chain을 사용하는 것보다 읽기 쉽다고 생각하지 않습니다.