[Python] 컴프리헨션(Comprehension)


Study/Python  2019. 12. 6. 09:00

안녕하세요. 명월입니다.


이 글은 Python에서 컴프리헨션(Comprehension)에 대한 글입니다.


Python에서 컴프리헨션이란 리스트나 딕셔너리, Set의 자료 구조를 보다 쉽게 검색, 추출할 수 있게 하는 문법입니다.

개인적으로 이는 C#의 Linq와 Java의 Stream식과 비슷한 구조라고 생각됩니다. 저같은 경우는 그렇게 생각해서 접근하니 이해하기 쉬웠습니다.


링크 - [C# 강좌 - 45] Linq 쿼리식

링크 - [Java강좌 - 32] Stream 식


먼저 리스트를 하나 만들어 보겠습니다.

# 리스트에 1부터 99까지의 데이터를 만듭니다.
list1 = list(range(1,100))
print(list1)
# 개행
print()
# list에서 x를 가져오고 if로 x%2 == 0 가 참인 조건으로 x를 실수 타입으로 변경해서 ret에 넣어라
ret = [float(x) for x in list1 if x%2 == 0]
print(ret)

결과를 보면 짝수의 값만 ret에 들어갔습니다.

위 식을 C#의 linq로 나타내면 「from x in list where x%2 == 0 select (float)x」와 똑같은 식이 되지 않을까 싶습니다.


제어문으로 표현하면 다음과 같습니다.

list1 = list(range(1,100))
ret = []
for x in list1:
  if x%2 == 0:
    ret.append(float(x))
print(ret)

리스트 컴프리헨션이 있으면 딕셔너리 컴프리헨션도 있습니다.

# 리스트에 1부터 99까지의 데이터를 만듭니다.
list1 = list(range(1,100))
print(list1)
print()
# 딕셔너리에서 키로 사용할 튜플입니다.
tuple1 = (3,5,7,9)
# 딕셔너리 컴프리헨션은 {키:값} 의 구조로 작성하면 됩니다.
# 아래의 식은 tuple를 루프로 키를 만들고 그 키에 해당하는 값인 list를 만들어서 튜플을 키로 하는 배수를 만드는 딕셔너리입니다.
dic1 = {t:[l for l in list1 if l%t==0] for t in tuple1}
print(dic1)

리스트와 딕셔너리를 만들었으면 Set도 만들수 있겠습니다.

# 리스트에 1부터 99까지의 데이터를 만듭니다.
list1 = list(range(1,100))
print(list1)
print()

# 3의 배수의 set를 만든다.
set1 = {x for x in list1 if x%3==0}
# 4의 배수의 set를 만든다.
set2 = {x for x in list1 if x%4==0}

# 3의 배수와 4의 배수의 교집합, 즉 12배수로 리스트를 만든다.
list2 = list(set1&set2)
# 정렬
list2.sort()
print(list2)

그 외에 컴프리헨션은 if를 중접할 수도 if ~ else 구조로 만들 수도 있습니다.

list1 = list(range(1,100))
set1 = {x for x in list1 if x%3==0}
set2 = {x for x in list1 if x%4==0}
list2 = list(set1&set2)
list2.sort()
##list2에는 12배수의 값이 있습니다.
print(list2)

# 10의 배수가 아니고 50이하만 list3으로 만든다.
list3 = [x for x in list2 if x%10!=0 if x<50]
print(list3)
print()

# 위 list3에서 30보다 큰 수는 10으로 나누고 작은 수는 10을 곱한다.
#if의 경우는 결과값이 앞에 놓이고 else의 경우는 뒤에 놓인다.
list4 = [x/10 if x>30 else x*10 for x in list3]
print(list4)

여기까지 기본적인 리스트(list), 딕셔너리(dictionary), 셋(set)의 컴프리헨션을 소개했습니다.

위의 형태를 보면 리스트는 대괄호([]), 딕셔너리와 셋은 중괄호를 ({})를 사용해서 컴프리헨션을 만들었는데 그럼 소괄호를 사용하면 튜플도 컴프리헨션이 되지 않을까 생각합니다.


튜플은 컴프리헨션이 존재하지 않고(애초에 튜플은 수정이 불가능함), 제네레이터 타입으로 변환합니다.

list1 = list(range(1,50))

generator = (x for x in list1 if x%2 == 0)
# 제네레이터 구조
print(generator)

print(next(generator))
print(next(generator))
print(next(generator))
print(next(generator))

제네레이터는 데이터 구조가 아니고 함수 구조이기 때문에 다음 글에서 자세히 소개하겠습니다.


여기까지 Python에서 컴프리헨션(Comprehension)에 대한 설명이었습니다.


궁금한 점이나 잘못된 점이 있으면 댓글 부탁드립니다.