40. 제너레이터

Joy·2020년 4월 3일
0

제너레이터 : 발생자

제너레이터: 이터레이터를 생성해주는 함수
이터레이터는 클래스에 iter, next 또는 getitem 메서드를 구현해야 하지만 제너레이터는 함수 안에서 yield라는 키워드만 사용하면 끝

  • yield 값
    함수 안에서 yield를 사용하면 함수는 제너레이터가 되며 yield에는 값(변수)을 지정

예)

def number_generator():
    yield 0
    yield 1
    yield 2
 
for i in number_generator():
    print(i)

yield를 사용하면 값을 함수 바깥으로 전달하면서 코드 실행을 함수 바깥에 양보합니다. 따라서 yield는 현재 함수를 잠시 중단하고 함수 바깥의 코드가 실행되도록

제너레이터는 함수를 끝내지 않은 상태에서 yield를 사용하여 값을 바깥으로 전달할 수 있습니다. 즉, return은 반환 즉시 함수가 끝나지만 yield는 잠시 함수 바깥의 코드가 실행되도록 양보하여 값을 가져가게 한 뒤 다시 제너레이터 안의 코드를 계속 실행하는 방식

제너레이터는 함수 끝까지 도달하면 StopIteration 예외가 발생
return도 함수를 끝내므로 return을 사용해서 함수 중간에 빠져나오면 StopIteration 예외가 발생

제너래이터 만들기

예)

def number_generator(stop):
n = 0              # 숫자는 0부터 시작
  while n < stop:    # 현재 숫자가 반복을 끝낼 숫자보다 작을 때 반복
      yield n        # 현재 숫자를 바깥으로 전달
      n += 1         # 현재 숫자를 증가시킴

for i in number_generator(3):
  print(i)

yield 에 함수

def upper_generator(x):
    for i in x:
        yield i.upper()    # 함수의 반환값을 바깥으로 전달
 
fruits = ['apple', 'pear', 'grape', 'pineapple', 'orange']
for i in upper_generator(fruits):
    print(i)

yeild from

값을 여러 번 바깥으로 전달 > 반복문 안해도 됨

  • yield from 반복가능한객체
  • yield from 이터레이터
  • yield from 제너레이터객체
def number_generator():
    x = [1, 2, 3]
    yield from x    # 리스트에 들어있는 요소를 한 개씩 바깥으로 전달
 
for i in number_generator():
    print(i)
def number_generator(stop):
    n = 0
    while n < stop:
        yield n
        n += 1
 
def three_generator():
    yield from number_generator(3)    # 숫자를 세 번 바깥으로 전달
 
for i in three_generator():
    print(i)

제너레이터 표현식

리스트 표현식을 사용할 때
리스트 표현식을 ( )(괄호)로 묶으면 제너레이터 표현식

문제: 소수 제너레이터 만들기

표준 입력으로 정수 두 개가 입력됩니다(첫 번째 입력 값의 범위는 10~1000, 두 번째 입력 값의 범위는 100~1000이며 첫 번째 입력 값은 두 번째 입력 값보다 항상 작습니다). 다음 소스 코드에서 첫 번째 정수부터 두 번째 정수 사이의 소수(prime number)를 생성하는 제너레이터를 만드세요. 소수는 1과 자기자신만으로 나누어 떨어지는 1보다 큰 양의 정수입니다.

답:

def prime_number_generator(start, stop):
    for n in range(start, stop):
        is_prime = True
        for i in range(2, n):
            if n % i == 0:
                is_prime = False
        if is_prime == True:
            yield n
  1. def로 제너레이터 만들기 - start 값이랑 stop 받기.

  2. 안에 for 이용해서 반복문. Start 값 ~ stop -1 까지 소수인지 아닌지 판별해야해.

  3. 사이의 수 n 빼면 그 수를 2~n직전 까지 나눠서 나머지가 0이 아닌 수가 소수임.
    is_prime을 true 로 놓고 나눠지는 수가 있어서 소수가 아니면 false로.

True 인수만 yield 사용해서 바깥으로 전달


개념이 너무 어렵다 ..

profile
roundy

0개의 댓글