같은 문법, 반대 의미
유일한 시각적 차이는 괄호. [x*x for x in nums] 는 list 컴프리헨션 — list 만들어 반환. (x*x for x in nums) 는 generator expression — lazy iterator 반환. 성능과 메모리 특성 완전히 달라.
generator expression 이 이기는 경우
세 가지. (1) 값을 한 번만 소비하고 다른 consumer (sum, any, all, max, min, for 루프) 에 먹일 때. (2) source 가 거대하거나 무한일 때. (3) short-circuit 원할 때 — 어떤 조건 만족하자마자 처리 멈추기. 셋 다 list 먼저 만드는 건 낭비.
list 컴프리헨션이 이기는 경우
결과를 두 번 이상 반복할 때, len()/인덱싱/슬라이싱 필요할 때, list 가 필요한 라이브러리 API 에 넘길 때. generator 는 그 어느 것도 지원 X. generator 를 그냥 기본 동작 활성화하려고 list(...) 로 감싸고 있으면 — 처음부터 list 컴프리헨션이 답.
괄호 생략 idiom
generator expression 이 함수 호출의 *유일한* 인자면 바깥 괄호 생략 가능. sum((x*x for x in nums)) 가 sum(x*x for x in nums) 와 같음. 가장 흔한 형태 — 대부분 generator expression 은 다른 함수의 괄호 안에 살아.
Pythonic Way: "~ 의 모든 원소 처리" 파이프라인의 디폴트는 generator expression 이어야 해. list 가 *명시적* 으로 필요할 때만 list 컴프리헨션. 대부분 초보가 list 컴프리헨션을 디폴트로 쓰고 10GB 로그 파일 반복하는 날 비용을 배워.