Python : 생성기 표현식 인쇄?


103

Python 셸에서 다음과 같은 목록 이해를 입력하면

>>> [x for x in string.letters if x in [y for y in "BigMan on campus"]]

멋지게 인쇄 된 결과를 얻습니다.

['a', 'c', 'g', 'i', 'm', 'n', 'o', 'p', 's', 'u', 'B', 'M']

사전 이해도 동일 :

>>> {x:x*2 for x in range(1,10)}
{1: 2, 2: 4, 3: 6, 4: 8, 5: 10, 6: 12, 7: 14, 8: 16, 9: 18}

생성기 표현식을 입력하면 다음과 같은 친숙한 응답을 얻지 못합니다.

>>> (x for x in string.letters if x in (y for y in "BigMan on campus"))
<generator object <genexpr> at 0x1004a0be0>

나는 이것을 할 수 있다는 것을 안다.

>>> for i in _: print i,
a c g i m n o p s u B M

그 외에 (또는 도우미 함수 작성) 대화 형 쉘에서 생성기 객체를 쉽게 평가하고 인쇄 할 수 있습니까?


2
여기서 진짜 문제는 무엇입니까? 무엇을 놓치고 있습니까?
Andreas Jung

3
@pynator : "진짜 문제"는 generator object대화식 프롬프트에서 대화식으로 이해를 구축 할 때 내용을 인쇄 할 수 있기를 원한다는 것 입니다. 전화 list(_)하면 그렇게됩니다. 내가 한 일은 목록 이해력을 사용한 다음 더 큰 코드에서 genexp로 변환하는 것입니다. 이는 목록 이해가 수행하지 않는 방식으로 런타임에 실패 할 수 있습니다.
늑대

5
짧은 대답은 생성기 표현식은 값이 존재하지 않기 때문에 인쇄 할 수 없다는 것입니다. 요청시 생성됩니다. 당신이 할 수있는 일은 (생성기가 언젠가 멈춘다 고 가정 할 때)와 같이 모든 값을 list()가져온 다음 인쇄하는 것입니다.
Kos

답변:


161

빠른 답변 :

이렇게 list()해서 생성 식 해결하여 (거의)을 갖는 정확히 동등한 []주위 브래킷. 그래, 당신은 할 수 있습니다

>>> list((x for x in string.letters if x in (y for y in "BigMan on campus")))

하지만 당신은 할 수 있습니다

>>> [x for x in string.letters if x in (y for y in "BigMan on campus")]

예, 그러면 생성기 표현식이 목록 이해력으로 바뀝니다. 그것은 똑같은 것이고 그것에 대해 list ()를 호출합니다. 따라서 생성기 표현식을 목록으로 만드는 방법은 그 주위에 대괄호를 두는 것입니다.

상해:

생성기 표현식은 "네이 키드" for표현식입니다. 이렇게 :

x*x for x in range(10)

이제 그 자체로는 한 줄에 붙일 수 없으며 구문 오류가 발생합니다. 그러나 주위에 괄호를 넣을 수 있습니다.

>>> (x*x for x in range(10))
<generator object <genexpr> at 0xb7485464>

공식 명칭은 여전히 ​​생성기 표현이라고 생각하지만 실제로는 차이가 없으며 괄호는 구문을 유효하게 만들기 위해서만 존재합니다. 예를 들어 함수에 유일한 매개 변수로 전달하는 경우에는 필요하지 않습니다.

>>> sorted(x*x for x in range(10))
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

기본적으로 Python 3 및 Python 2.7에서 사용할 수있는 다른 모든 이해는 생성기 표현식을 둘러싼 구문 설탕 일뿐입니다. 이해력 설정 :

>>> {x*x for x in range(10)}
{0, 1, 4, 81, 64, 9, 16, 49, 25, 36}

>>> set(x*x for x in range(10))
{0, 1, 4, 81, 64, 9, 16, 49, 25, 36}

딕트 이해력 :

>>> dict((x, x*x) for x in range(10))
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}

>>> {x: x*x for x in range(10)}
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}

그리고 Python 3에서 이해력을 나열하십시오.

>>> list(x*x for x in range(10))
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

>>> [x*x for x in range(10)]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

Python 2에서 목록 이해는 단순한 구문 설탕이 아닙니다. 그러나 유일한 차이점은 x가 Python 2에서 네임 스페이스로 누출된다는 것입니다.

>>> x
9

Python 3에서는

>>> x
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined

이것은 Python에서 생성기 표현식의 내용을 멋지게 출력하는 가장 좋은 방법은 목록을 이해하는 것입니다! 그러나 이미 생성기 객체가있는 경우에는 분명히 작동하지 않습니다. 이렇게하면 하나의 생성기 목록이 생성됩니다.

>>> foo = (x*x for x in range(10))
>>> [foo]
[<generator object <genexpr> at 0xb7559504>]

이 경우 다음으로 전화해야합니다 list().

>>> list(foo)
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

이것은 작동하지만 다소 어리 석습니다.

>>> [x for x in foo]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

5
공식 용어는 "제너레이터 표현"으로 남아 있습니다. "이해력"이라는 단어가 반복을 의미하기 때문입니다. 이 질문과 답변이 잘 설명되어 있듯이 genexp 수행 하지 않는 한 가지입니다. :)
ncoghlan

2
list( generator-expression )생성기 표현식을 인쇄하지 않습니다. 목록을 생성하고 대화식 쉘에서 인쇄합니다. 목록을 생성하는 대신 Python 3에서 생성기 표현식을 print 문에 스플래 팅 할 수 있습니다. 즉) print(*(generator-expression)). 이렇게하면 시작과 끝에 쉼표없이 대괄호없이 요소가 인쇄됩니다.
AJNeufeld

17

목록이나 사전과 달리 생성기는 무한 할 수 있습니다. 이렇게하면 작동하지 않습니다.

def gen():
    x = 0
    while True:
        yield x
        x += 1
g1 = gen()
list(g1)   # never ends

또한 발전기를 읽으면 변경되므로 완벽한 방법은 없습니다. 생성기의 출력 샘플을 보려면 다음을 수행 할 수 있습니다.

g1 = gen()
[g1.next() for i in range(10)]

2
제너레이터가 무한 할 수 있으므로 루프 또는 전체 중단을 유발할 수 있다는 진술 때문에 투표되었습니다 (사양에 따라 다름).
Milan Velebit

16

다음 호출에서 표현식을 래핑 할 수 있습니다 list.

>>> list(x for x in string.letters if x in (y for y in "BigMan on campus"))
['a', 'c', 'g', 'i', 'm', 'n', 'o', 'p', 's', 'u', 'B', 'M']

15

또는 map중간 목록을 작성할 필요없이 항상 반복자를 통해 수행 할 수 있습니다 .

>>> _ = map(sys.stdout.write, (x for x in string.letters if x in (y for y in "BigMan on campus")))
acgimnopsuBM

3
이것은 거대한 물체를 만들지 않고 실제로 제너레이터의 내용을 인쇄하는 유일한 대답입니다.
Marek R

2
>>> list(x for x in string.letters if x in (y for y in "BigMan on campus"))
['a', 'c', 'g', 'i', 'm', 'n', 'o', 'p', 's', 'u', 'B', 'M']

생성기가 무한한 경우 루프가 발생합니다.
Milan Velebit
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.