목표
list comprehension은 list를 쉽고 빠르게 만들수 있는 방법이다.
예를 들어 요소 1, 2, 3, 4, 5 를 가지고있는 리스트를 만들고 싶다고 가정한다.
예시
L = []
for i in range(0,6) :
L.append(i)
List comprehension을 이용하면 간단하게 한줄로 표기가 가능하다.
L = [i for i in range(0,6)]
위 형태의 형식을 따르면 생성이 가능하다.
잠깐! 여기서 if 문을 사용할때 break, countinue 같은 if문안에 쓰는 용어는 사용이 불가능하다.
generator는 모든 값을 메모리에 저장하지 않고 그때 그때 값을 생성해서 반환하기 때문에 iterable을 사용할때 한번에 한번의 값만 순환시킨다.
특이한 점은 return 대신 yield를 사용한다는 것이다.
yield는 값을 반환시킨후 함수를 정지시킨다. return 은 값을 반환하고 그대로 함수가 종료되는 면에서 둘은 차이점을 보인다.
L = (i for i in range(0,6))
Generator는 ()를 사용한다.
둘의 차이점은
List_comprehension = [z for i in my_list]
Generator = (z for i in my_list)
[]를 사용하는것과 ()를 사용하는 차이점이 있다.
return
List comprehension은 List를 반환하지만
Generator은 generator를 반환한다.
메모리
List의 경우는 list 안에 속한 모든 데이터를 메모리에 적재하기 때문에 list의 크기 만큼 차지하는 메모리 사이즈가 늘어나게 된다.
하지만 generator는 데이터 값을 한꺼번에 메모리에 적재 하는 것이 아니라 next() 메소드를 통해 차례로 값에 접근할 때마다 메모리에 적재하는 방식이다.
시간
예시로 보겠슴니다
import time
def print_iter(iter):
for element in iter:
print(element)
def lazy_return(num):
print("sleep 1s")
time.sleep(1)
return num
print("comprehension_list=")
comprehension_list = [ lazy_return(i) for i in L ]
print_iter(comprehension_list)
print("generator_exp=")
generator_exp = ( lazy_return(i) for i in L )
print_iter(generator_exp)
이를 실행하면 결과는
list comprehension의 경우 모든 값을 먼저 수행하기 때문에 sleep인 3초 후에 print_iter(comprehension_list)를 수행합니다.
반면에 generator의 경우 generator 를 생성할 때는 실제 값을 로딩하지 않고, for 문이 수행 될때 하나씩 sleep_func()을 수행하며 값을 불러오게 된다. 수행 시간이 긴 연산을 필요한 순간까지 늦출 수 있다는 점이 특징이다.
앞서 차이점에서 말했듯이 generator는 값을 하나씩 반환하기 때문에 전부 수행하고 메모리에 저장하는 리스트와 비교했을때 메모리공간의 낭비가 없고 시간문제에 있어서 효율적으로 사용할 수 있다.