[Python] Skill of coding - 리스트 대신 제너레이터?

Hyeseong·2020년 12월 9일
0

python skill of coding

목록 보기
9/18

리스트를 반환하는 대신 제너레이터를 고려하자
일련의 결과를 생성하는 함수에서 택할 가장 간단한 방법은 아이테므이 리스트를 반환하는 것이에요. 예를 들어 문자열에 있는 모든 단어의 인덱스를 출력하고 싶다고 하자. 다음 코드에서는 append 메서드로 리스트에 결과들을 누적하고 함수가 끝날 때 해당 리스트를 반환한다.

address = 'Four score and seven years ago...'
address = 'Four score and seven years ago our fathers brought forth on this continent a new nation, conceived in liberty, and dedicated to the proposition that all men are created equal.'
result = index_words(address)
print(result[:3])
[0, 5, 11]

두 가지 문제점

하나

깔끔하지 않음. 새로운 결과가 나올 때마다 append 메서드를 호출해야해요. 메서드 호출(result.append)이 많아서 리스트에 추가하는 값(index+1)이 덜 중요해 보입니다. 결과 리스트를 생성하는 데 한줄이 필요하고 , 그 값을 반환하는데도 한 줄이 필요해요. 함 수 몸체에 문자가 130가량(공백 제외) 있지만 그 중에서 중요한 문자는 약 75개에요.

이 함수를 작성하는 더 좋은 방법은 제너레이터를 사용하는 거죠. 제너레이터는 yield 표현식을 사용하는 함수에요. 제너레이터 함수는 호출되면 실제로 실행하지 않고 바로 이터레이트를 반환해요. 내장함수 next를 호출할 때마다 이터레이터는 제너레이터가 다음 yield표현식으로 진행하게 해요. 제너레이터에서 yield에 전달한 값을 이터레이터가 호출하는 쪽에 반환해요.

result = list(index_words_iter(address))
print(result[:3])
[0, 5, 11]

리스트와 연동하는 부분이 모두 사라져서 훨씬 이해하기 쉬워졌네요. 결과는 리스트가 아닌 yield 표현식으로 전달되요. 제너레이터 호출로 반환되는 이터레이터를 내장함수 list에 전달하면 손쉽게 리스트로 변환 할 수 있어요.

맨 처음 index_words함수의

두번째

반환하기 전에 모든 결과를 리스트에 저장해야 한다는 점이에요. 입력이 매우 많다면 프로그램 실행 중에 메모리가 고갈되어 동작을 멈추는 원인이되요. 반면에 제너레이터로 작성한 버전은 다양한 길이의 입력에도 쉽게 이용됩니다.
다음은 파일에서 입력을 한 번에 한 줄씩 읽어서 한 번에 한 단어씩 출력을 내어주는 제너레이터에요. 이 함수가 동작 할 때 메모리는 입력 한 줄의 최대 길이까지에요.

address_lines = """Four score and seven years
ago our fathers brought forth on this
continent a new nation, conceived in liberty,
and dedicated to the proposition that all men
are created equal."""

with open('address.txt', 'w') as f:
    f.write(address_lines)
[0, 5, 11]

핵심 정리

  • 제너레이터를 사용하는 방법이 누적된 결과의 리스트를 반환하는 방법보다 이해하기에 명확하다
  • 제너레이터에서 반환한 이터레이터는 제너리에터 함수의 본문에 있는 yield 표현식에 전달된 값들의 집합이다.
  • 제너레이터는 모든 입력과 출력을 메모리에 저장하지 않으므로 입력값의 양을 알기 어려울 때도 연속된 출력을 만들수 있다.
profile
어제보다 오늘 그리고 오늘 보다 내일...

0개의 댓글