제너레이터는 지연 평가(lazy evaluation) 구현체이다.

파이썬에서 모든 lazy evalution은 이터레이터(iterator)라고 불린다.
이러한 이터레이터 중에서 특정 방식을 통해서 생성한 이터레이터를 제너레이터라고 부른다.

즉, 객체의 값을 미리 생성해서 저장해 두지 않고 해당 객체를 사용할 때 값을 계산해서 반환해준다.

 

제너레이터는 소괄호()를 이용한 컴프리헨션으로 생성할 수 있다.

num = (x for x in range(10))
print(num)

>><generator object <genexpr> at 0x00000214166F4AC8>

 

위의 설명처럼 객체를 사용할 때 값을 계산해주므로 for문으로 제너레이터를 사용해보면

num = (x for x in range(10))
for x in num:
    print(x, end=' ')
    
>>0 1 2 3 4 5 6 7 8 9 

next함수로도 제너레이터의 사용이 가능하다. next함수는 제너레이터의 다음 값을 반환해준다.

num = (x for x in range(3))
print(next(num))
print(next(num))
print(next(num))

>>0
>>1
>>2

정해진 범위를 벗어나면 StopIteration 에러가 발생한다.

num = (x for x in range(3))
print(next(num))
print(next(num))
print(next(num))
print(next(num))

>>0
1
2
Traceback (most recent call last):
  File "..............................", line 5, in <module>
    print(next(num))
StopIteration

 

제너레이터는 다른 이터레이터(iterator)와 달리 값을 계산해서 반환해주고 나면 값을 소비하고 더 이상 기억하지 않는다.

(재사용이 불가능하다.)

num = (x for x in range(10))
for x in num:
    print(x, end=' ')

for x in num:			#두 번째 for문에서는 아무것도 출력이 되지않는다.
    print(x, end=' ')
    
>>0 1 2 3 4 5 6 7 8 9 

 

 

yield를 이용한 제너레이터 생성


def문을 이용한 함수 내부에 yield 키워드를 사용하여 제너레이터의 생성이 가능하다.

아래와 같이 값을 단순 지정해줄 수도 있고

def gen():
    yield 0
    yield 1
    yield 2

x=gen()		#제너레이터 x 생성
for i in x:
    print(i)
    
>>0
1
2

보통 함수와 같이 내부에 for문과 if문을 사용할 수도 있다.

def gen():
    for i in range(3):
        yield i

x=gen()
for i in x:
    print(i)
    
    
>>0
1
2
파이썬은 함수 내부에 yield 키워드가 하나라도 존재하면 해당 함수를 generator로 인식한다.

아래와 같이 함수에 인자를 받으면 더 다양한 제너레이터를 생성할 수 있다.

또한 반복문을 이용하여 매번 다른 값을 생성하여 반환해준다면 재사용도 가능할 것이다.

import random

def broken_dice(n):     #1~6까지의 주사위 값중 n을 제외하고 리턴
    while True:
        number = random.randint(1, 6) # 1~6까지 정수 중 랜덤하게 숫자를 뽑는다.
        if number != n: #  랜덤하게 뽑은 숫자, n이 아니라면 리턴
            yield number

dice=broken_dice(5)
for i in range(6):
    print(next(dice))
    
>>2
2
2
1
1
4

 

 

출처:https://wikidocs.net/22802

'Python' 카테고리의 다른 글

Python - 컴프리헨션(Comprehension)  (0) 2020.08.25
Python - 람다함수(익명함수)  (0) 2020.08.24
Python - 전역 변수, 지역 변수  (0) 2020.08.23
Python - mutable객체, immutable객체  (0) 2020.08.22
Python - 빠른 입력  (0) 2020.08.17

파이썬은 컴프리헨션이라는 문법을 지원한다.

컴프리헨션을 이용하면 list, dict, set을 좀 더 간단한 방법으로 작성할 수 있다.

 

 

리스트 컴프리헨션


리스트 컴프리헨션의 작성법은 아래와 같다.

num = [x for x in range(10)]

위의 컴프리헨션문을 for문으로 표기하면 아래와 같다.

num = []
for x in range(10):
	num.append(x)
 

 

append(x)를 대신하여 컴프리헨션문에서는 for문 앞에 변수명만 적어주면 된다.

 

 

컴프리헨션문 내에서 if문과 다중 for문도 사용이 가능하다.(if문도 여러개 사용 가능)

num = [x for x in range(10) if x%2==0]  #if문을 이용하여 짝수만 저장
print(num)

>>[0, 2, 4, 6, 8]

 

 

다중 for문 작성법(왼쪽 for문이 먼저 작동한다.)

num=[[x,y] for x in [1,2,3] for y in [4,5,6]]
print(num)

>>[[1, 4], [1, 5], [1, 6], [2, 4], [2, 5], [2, 6], [3, 4], [3, 5], [3, 6]]

 

 

셋 컴프리헨션


위 리스트 컴프리헨션의 대괄호[]만 중괄호{}로 바꿔주면된다. 내부 코드 작성법은 동일.

 

 

 

딕셔너리 컴프리헨션


컴프리헨션문을 중괄호{}로 감싸고 key:value의 형태로 내용을 채우면 딕셔너리의 생성이 가능하다.

li = ['A','B','C']
di = {x:0 for x in li}	#value는 0
print(di)

>>{'A': 0, 'B': 0, 'C': 0}

 

컴프리헨션을 이용하여 기존 딕셔너리를 새롭게 변경할 수도 있다.

old={'A':10,'B':10,'C':20,'D':10}
new={k:v for k,v in old.items() if v!=20}	#items메소드를 이용해 old에서 key와 value를 가져옴
print(new)

>>{'A': 10, 'B': 10, 'D': 10}	#if문을 이용해 20이라는 value를 가진 key 제거

 

 

 

튜플 컴프리헨션


위의 방법대로라면 소괄호()를 사용하여 튜플 컴프리헨션을 작성할 수 있을 것 같다.

num = (x for x in range(10))
print(num)

>><generator object <genexpr> at 0x00000220CCDD4AC8>

하지만 생각과 달리 generator(제너레이터)가 생성된다.

제너레이터에 대해서는 다음 글에서 설명하겠다.

 

'Python' 카테고리의 다른 글

Python - 제너레이터(Generator)  (0) 2020.08.25
Python - 람다함수(익명함수)  (0) 2020.08.24
Python - 전역 변수, 지역 변수  (0) 2020.08.23
Python - mutable객체, immutable객체  (0) 2020.08.22
Python - 빠른 입력  (0) 2020.08.17

파이썬에서 함수는 기본적으로 def를 이용하여 작성하지만, 람다를 사용하면 좀 더 간결한 코드로 작성이 가능하고 메모리 절약도 가능하다.

lambda <<매개변수>>: <<리턴값>>

람다함수는 위와 같은 형태로 작성한다.

 

 

람다함수의 또 다른 이름이 익명함수인 만큼 "이름 없는 함수"로 작성이 가능하다.

함수의 이름이 정해지지 않았으니 재사용은 불가능하다.

print((lambda x:x**2)(3))	#람다함수는 정의와 동시에 사용할 수 있다.

>>9

 

 

하지만 람다함수를 변수에 저장하게 되면 def문을 이용해서 작성한 함수와 똑같이 재사용이 가능하다.

f=lambda x:x**2		#f에 람다함수 저장
print(f(3))

>>9

 

 

 

람다함수는 보통 아래와 같이 딱 한번 필요한 함수를 정의하는데 자주 사용된다.

li=[1,2,3,4,5]
li=list(map(lambda x:x**2,li))
print(li)

>>[1, 4, 9, 16, 25]

 

'Python' 카테고리의 다른 글

Python - 제너레이터(Generator)  (0) 2020.08.25
Python - 컴프리헨션(Comprehension)  (0) 2020.08.25
Python - 전역 변수, 지역 변수  (0) 2020.08.23
Python - mutable객체, immutable객체  (0) 2020.08.22
Python - 빠른 입력  (0) 2020.08.17

+ Recent posts