[python] Python : 생성기 표현식 인쇄?

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

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



답변

빠른 답변 :

이렇게 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]


답변

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

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)]


답변

다음 호출에서 표현식을 래핑 할 수 있습니다 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']


답변

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

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


답변

>>> 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']


답변