소개
이 섹션에서는 제너레이터 표현식과 itertools 모듈을 포함하여 몇 가지 추가적인 제너레이터 관련 주제를 소개합니다.
이 섹션에서는 제너레이터 표현식과 itertools 모듈을 포함하여 몇 가지 추가적인 제너레이터 관련 주제를 소개합니다.
리스트 컴프리헨션 (list comprehension) 의 제너레이터 버전입니다.
>>> a = [1,2,3,4]
>>> b = (2*x for x in a)
>>> b
<generator object at 0x58760>
>>> for i in b:
... print(i, end=' ')
...
2 4 6 8
>>>
리스트 컴프리헨션과의 차이점:
일반적인 구문:
(<expression> for i in s if <conditional>)
함수 인수로도 사용할 수 있습니다.
sum(x*x for x in a)
모든 이터러블 (iterable) 에 적용할 수 있습니다.
>>> a = [1,2,3,4]
>>> b = (x*x for x in a)
>>> c = (-x for x in b)
>>> for i in c:
... print(i, end=' ')
...
-1 -4 -9 -16
>>>
제너레이터 표현식의 주요 사용 사례는 시퀀스에 대해 어떤 계산을 수행하지만 결과를 한 번만 사용하는 코드입니다. 예를 들어, 파일에서 모든 주석을 제거하는 경우입니다.
f = open('somefile.txt')
lines = (line for line in f if not line.startswith('#'))
for line in lines:
...
f.close()
제너레이터를 사용하면 코드가 더 빠르게 실행되고 메모리를 적게 사용합니다. 스트림에 적용되는 필터와 같습니다.
itertools 모듈itertools는 이터레이터 (iterators) / 제너레이터 (generators) 를 돕도록 설계된 다양한 함수를 포함하는 라이브러리 모듈입니다.
itertools.chain(s1,s2)
itertools.count(n)
itertools.cycle(s)
itertools.dropwhile(predicate, s)
itertools.groupby(s)
itertools.ifilter(predicate, s)
itertools.imap(function, s1, ... sN)
itertools.repeat(s, n)
itertools.tee(s, ncopies)
itertools.izip(s1, ... , sN)
모든 함수는 데이터를 반복적으로 처리합니다. 다양한 종류의 반복 패턴을 구현합니다.
자세한 내용은 PyCon '08 의 Generator Tricks for Systems Programmers 튜토리얼을 참조하십시오.
이전 연습에서 로그 파일에 기록되는 줄을 따라가서 이를 일련의 행으로 구문 분석하는 코드를 작성했습니다. 이 연습은 이를 기반으로 계속 진행됩니다. stocksim.py가 여전히 실행 중인지 확인하십시오.
제너레이터 표현식은 리스트 컴프리헨션 (list comprehension) 의 제너레이터 버전입니다. 예를 들어:
>>> nums = [1, 2, 3, 4, 5]
>>> squares = (x*x for x in nums)
>>> squares
<generator object <genexpr> at 0x109207e60>
>>> for n in squares:
... print(n)
...
1
4
9
16
25
리스트 컴프리헨션과는 달리, 제너레이터 표현식은 한 번만 사용할 수 있습니다. 따라서 다른 for 루프를 시도하면 아무것도 얻을 수 없습니다:
>>> for n in squares:
... print(n)
...
>>>
제너레이터 표현식은 때때로 함수 인자에 배치됩니다. 처음에는 약간 이상해 보일 수 있지만, 다음 실험을 시도해 보십시오:
>>> nums = [1,2,3,4,5]
>>> sum([x*x for x in nums]) ## A list comprehension
55
>>> sum(x*x for x in nums) ## A generator expression
55
>>>
위의 예에서, 제너레이터를 사용하는 두 번째 버전은 큰 리스트를 조작하는 경우 메모리를 훨씬 적게 사용합니다.
portfolio.py 파일에서 리스트 컴프리헨션을 포함하는 몇 가지 계산을 수행했습니다. 이를 제너레이터 표현식으로 바꿔보십시오.
제너레이터 표현식은 종종 작은 제너레이터 함수를 대체하는 데 유용합니다. 예를 들어, 다음과 같은 함수를 작성하는 대신:
def filter_symbols(rows, names):
for row in rows:
if row['name'] in names:
yield row
다음과 같이 작성할 수 있습니다:
rows = (row for row in rows if row['name'] in names)
ticker.py 프로그램을 수정하여 적절하게 제너레이터 표현식을 사용하십시오.
축하합니다! 더 많은 제너레이터 (Generators) 랩을 완료했습니다. LabEx 에서 더 많은 랩을 연습하여 실력을 향상시킬 수 있습니다.