[Python] Comprehension (list, dict, set) and Generator Expression

2023. 6. 6. 14:57·Programming
728x90
728x90

List Comprehension

List comprehension is an expression(표현식)
that transforms a collection (not necessarily a list) into a list.

list를 생성하는 expression 으로,
원본이 되는 collection 의 모든 item 혹은 일부 item들에 대해 같은 operation을 적용하여
새로운 list (사실은 collection 또는 generator) 를 생성한다.

 

  • 사실 list comprehension 은 일종의 shorthand expression으로 중첩된 여러 반복문(loop) 및 조건문(if)으로 collection을 생성하는 것을 한 줄로 작성가능하게 해준다.
  • list comprehension은
    • collection을 입력으로 받고,
    • 해당 collection의 item들에 대해 하나 하나씩 방문(iterate)하고
    • 이들에 대해 지정된 boolean expression으로 evaluation(True인지 False인지 값을 얻는 처리)하여
      일종의 filtering을 한 이후
      ,
    • 지정된 loop expression으로 transform을 수행한 결과 를
    • 결과 collection에 item으로 추가 한다.

 

이를 글로 간단히 정리한 list comprehension 은 동작 과정은 다음과 같음.

  1. list-comprehension expression은 원본이 되는 collection 에 대해 iteration을 수행하여 각 item을 얻어옴.
  2. 얻어진 item들에 대해 optional Boolean expression 이 수행(evaluation)됨.
  3. 해당 Boolean expression이 True인 경우,
    loop expression이 해당 item에 대해 수행되어 값이 얻어지고(=loop expression을 통해 transform이 이루어짐),
    이 값이 결과 list에 item으로 추가됨.
  4. 해당 Boolean 표현식이 False인 경우, 해당 itme은 무시됨.

그 외의 Comprehensions

사실comprehension 은 list 외의 collection들,

set, dict, tuple 들에도 적용가능하다

tuple의 경우는 immutable sequence를 위한 generator를 만들어냄: Generator Expression


Generator Comprehension (or Generator Expression)

tuple로 comprehension을 만들 경우,

generator를 반환해주는데

이를 generator expression이라고도 부른다.

 

list-comprehension에서 square bracket을 parenthesis (or round bracket)으로만 바꾸면 된다.

generator의 장점은 메모리를 효율적으로 사용한다는 점임: Lazy Evaluation

yield를 이용한 방식보다 tuple을 통한 comprehension으로 generator를 구현한 경우는
function이 아닌 expression으로 구현하기 때문에 표현이 보다 심플해진다.

 

하지만, 복잡한 로직의 generator 구현에는 generator expression보다는
yield를 통한 generator function 을 사용하는 것이 보다 낫다.


list-comprehension 문법

  • 앞서 설명한 loop expression 은 comprehension을 사용하지 않은 경우에는 반복문 내부에 들어갈 expression(표현식)이고,
  • boolean expression은 원본이 되는 collection의 item들 중 어떤 것들을 loop exression으로 넘길지 말지를 결정하는 일종의 filter 역할을 수행하는 True와 False를 반환하는 expression(표현식)이다. (True를 반환하는 item만이 loop express로 넘겨짐)

 

이들이 list comprehension 구문에서 놓여지는 위치는 다음과 같다.

ret_list = [ loop_expression for x in src_list if boolean_expression ]
  • 참고로 위와같이 square bracket 을 사용하면 결과 collection이 list로 결정된다.
    • 만일 curly bracket 이라면 set 또는 dict가 된다. (loop exression 부분에 key : value 형태로 놓이면 dict, 단일 값의 expression이면 set)
    • 당연히 parenthesis 라면 tuple에 해당하며, 이 경우는 결과 tuple에 해당하는 generator가 만들어진다.
  • 위의 예에서는 for 문에서 x 변수를 사용하였기 때문에 src_list(원본 list)의 item들이 iterate되면서 x에 할당된다.
  • 이후, boolean_expression에서 현재 x에 대해 조건을 확인하고 True시 loop expression으로 넘겨짐.
  • boolean_expression은 생략가능하며, 생략시 src_list의 모든 item 들이 loop expression으로 넘겨짐.

Examples

다음의 예제 코드를 살펴보면서 list-comprehension의 사용방법을 익숙해지도록 한다.

# src_list를 shallow copy. 
# ret_list = src_list.copy() 또는 ret_list = src_list[:] 와 같은 결과임.
# 이 경우엔 comprehension을 사용하는 건 상대적으로 비효율적이라 이런 방식으로 거의 사용되지 않음.
ret_list = [x for x in src_list]

# non-negative filter를 적용하여 ret_list를 생성.
ret_list = [x for x in src_list if x >= 0]

# 3제곱 (cube of a number) 처리를 한 ret_list생성.
ret_list = [x**3 for x in src_list]

# 역수(valid reciprocal) 처리 (단 0으로 나누어지는 경우 제외)
ret_list = [1/x for x in src_list if x != 0]

# multi_line text로 구성된 file을 읽어들여 공백 line을 제거.
ret_lit = [line for line in [l.strip() for l in infile] if line != ""]
  • 많이 사용되면서 해석하기 어렵지 않은 예제들임.
  • 단, 맨 마지막과 같이 list comprehension 들을 중첩시키는 것도 가능하다는 것을 명심할 것.
    • 개인적으로 2회 이상 중첩되는 comprehension은 가독성이 너무 떨어진다. (가독성 측면에서 comprehension에서 중첩은 한번으로 족하다.)
    • 사실 comprehension을 중첩시키지 않고, comprehension 내의 for문을 여러번 사용할 수도 있으나 이것도 2회 이상의 중첩이 필요하다면 일반 반복문으로 구현하는게 좋다.

list comprehension에서, loop expressoin 이나 boolean expression 이 각각 2회 초과하여 사용되는 경우도 권장되지 않는다.


이중 for 문

다음은 구구단의 결과값을 가지는 일렬로 가지는 list임.

ret_list = [ i * j for i in range(2,10) for j in range(1,10)]

# 위의 코드를 일반 반복문으로 구현
ret_list0 = []
for i in range(2,10):
    for j in range(1,10):
        ret_list0.append(i*j)

print(ret_list)
print(ret_list0)

앞에 있는 for문이 바깥쪽이고 뒤의 for문이 안쪽에 위치함.


matrix등의 접근

많이 사용되는 처리방식은 아니지만, list comprehension에 대한 이해에 도움이 되는 예제임.

m = [
     [1, 2, 3],
     [4, 5, 6],
     [7, 8, 9]
    ]

m_ravel = [x for row in m for x in row]
  • 중첩된 list를 flattening한 결과를 얻음.

boolean expression 여러 개 사용하기.

2 또는 3의 배수만을 추출하여 결과 list를 만드는 예제는 다음과 같음.

ret_list = [x for x in range(1,101) if x % 2 == 0 or x % 3 == 0]

 

권장하지는 않지만 if 를 연속으로 기재하는 경우 and로 처리된다 (가독성 때문에 권하지 않음).

아래 예제는 2의 배수이면서 동시에 3의 배수인 수들을 추출한다.

ret_list = [x for x in range(1,101) if x % 2 == 0 if x % 3 ==0]
  • 이전의 예제가 or로 명시적으로 처리된 것과 달리 위의 경우는 and로 처리됨.

재밌는 건 위와 같이 2개의 if문 사이에 or를 넣을 경우
SyntaxError가 발생한다.

 

다음이 같은 결과를 내는 다른 방법으로 단일 if문에 복수의 조건을 사용했다 (권장).

ret_list = [x for x in range(1,101) if x%2 == 0 and x % 3 == 0]

같이 보면 좋은 자료들

https://ds31x.tistory.com/122

 

[Python] Collections

Python에는 여러 데이터를 담아두고 다룰 수 있는 다양한 컬렉션(collection) 클래스들이 있음.대표적으로 list, tuple, set, dict 등이 있는데 이들의 기능을 설명하는 abstract base class들로부터 시작하여 각

ds31x.tistory.com

 


 

728x90

'Programming' 카테고리의 다른 글

[Python] range and enumerate  (0) 2023.06.07
[Python] Iterable and Iterator, plus Generator  (1) 2023.06.07
[Python] Assignment와 Shallow Copy, Deep Copy  (0) 2023.06.05
[Programming] Garbage Collection (GC)  (0) 2023.06.05
[Python] Interpreter and PVM (Python Virtual Machine)  (2) 2023.06.05
'Programming' 카테고리의 다른 글
  • [Python] range and enumerate
  • [Python] Iterable and Iterator, plus Generator
  • [Python] Assignment와 Shallow Copy, Deep Copy
  • [Programming] Garbage Collection (GC)
dsaint31x
dsaint31x
    반응형
    250x250
  • dsaint31x
    Dsaint31's blog
    dsaint31x
  • 전체
    오늘
    어제
    • 분류 전체보기 (784)
      • Private Life (14)
      • Programming (205)
        • DIP (116)
        • ML (34)
      • Computer (119)
        • CE (53)
        • ETC (33)
        • CUDA (3)
        • Blog, Markdown, Latex (4)
        • Linux (9)
      • ... (368)
        • Signals and Systems (115)
        • Math (176)
        • Linear Algebra (33)
        • Physics (43)
        • 인성세미나 (1)
      • 정리필요. (61)
        • 의료기기의 이해 (6)
        • PET, MRI and so on. (7)
        • PET Study 2009 (1)
        • 방사선 장해방호 (5)
        • 방사선 생물학 (3)
        • 방사선 계측 (9)
        • 기타 방사능관련 (3)
        • 고시 (9)
        • 정리 (18)
      • RI (0)
      • 원자력,방사능 관련법 (2)
  • 블로그 메뉴

    • Math
    • Programming
    • SS
    • DIP
  • 링크

    • Convex Optimization For All
  • 공지사항

    • Test
    • PET Study 2009
    • 기타 방사능관련.
  • 인기 글

  • 태그

    인허가제도
    Programming
    Probability
    Vector
    Optimization
    function
    signals_and_systems
    opencv
    linear algebra
    SS
    cv2
    numpy
    fourier transform
    Python
    Term
    SIGNAL
    random
    math
    ML
    signal_and_system
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
dsaint31x
[Python] Comprehension (list, dict, set) and Generator Expression
상단으로

티스토리툴바