List Comprehension

seyong·2021년 12월 18일
4
post-thumbnail

리스트 컴프리헨션이란?

리스트 컴프리헨션이란 쉽게 말해,
리스트를 쉽게, 짧게 한 줄로 만들 수 있는 파이썬의 문법이며,
리스트를 쉽게 만들면서 동시에 리스트를 반환한다.
여기중요한 포인트는 바로 쉽게, 짧게 한줄로 만들수 있는 이다.

보통 배열을 만들고 사용할 때는 선언과 할당을 같이 하고, 선언만 하거나 할당만 하는 경우는 없기 때문에 이 작업을 간편하게 한 줄로 해결하는 것이 리스트 컴프리헨션이다.

리스트 컴프리헨션의 기본적인 문법

리스트 컴프리헨션의 기본적인 문법은 다음과 같다.

[( 변수를 활용한 값 ) for ( 사용할 변수 이름 ) in ( 순회할 수 있는 값 )]

배열을 만들고 for 반복문 안에서 각 원소의 값을 할당하는 작업이 이 한 줄로 일어난다.

  • 변수를 활용한 값
    ➡ for앞에서 실제로 배열의 각 원소의 할당될 값을 적는다.

  • 사용할 변수 이름
    ➡ 파이썬의 for 문에서 ‘for’와 ‘in’ 사이에 for 블락 안에서 사용될 인자의 이름을 쓰는 것과 같다

  • 순회할 수 있는 값
    ➡ range 처럼 값을 하나씩 살펴볼 수 있는 것을 총칭한다
    range 뿐만 아니라 다른 리스트, set, dict, tuple 등도 될 수 있다. 일반 for문에서 쓸 수 있는 모든 값이 들어갈 수 있는 것이다.

다음 예제코드를 보자.

arr = []

for i in range(10):
	arr.append(i * i)

print(arr)

#[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

우선 위의코드는 빈배열을 먼저 만들고
for 반복문을 사용하여 0부터 9까지 순회하면서 자기자신을 곱한 후
빈 배열인 arr 에 그 값을 각각추가한다.
이 간단한 반복문을 리스트 컴프리헨션으로 바꿔서 작성해보면 매우 간단하게 한줄로 작성할 수 있다. 아래코드를 보자.

 # 리스트 컴프리헨션
 arr = [i * i for i in range(10)]
 
 print(arr)

# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

리스트 안에 식, for, 변수, in, 리스트 순서로 들어있지만 뒤에서 앞으로 읽으면 간단하다. 즉, range(10)으로 0부터 9까지 생성하여 변수 i에 숫자를 꺼내고, 최종적으로 i를 이용하여 리스트를 만든다는 뜻이다.

for 반복문은 빈 list를 만들고 거기에 요소를 하나하나 집어넣는 느낌이라면 리스트컴프리헨션은 list 및 list안에 들어갈 요소까지 한번에 선언하는 느낌이다.

글로만 설명하면 이해가 잘 안될수있으니 잘 설명된 이미지를 참고하자.
아래 이미지는 리스트 컴프리헨션의 동작 순서를 잘 설명해준다.

a = [i for i in range(10)] # 0부터 9까지 숫자를 생성하여 리스트 생성
 print(a)
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

위에 예제에서 i에다가 다른 값과의 연산을 추가하여 새로운 리스트를 만들어보겠다.


b = [i + 5 for i in range(10)]    # 0부터 9까지 숫자를 생성하면서 값에 5를 더하여 리스트 생성

print(b)

# [5, 6, 7, 8, 9, 10, 11, 12, 13, 14]

c = [i * 2 for i in range(10)]    # 0부터 9까지 숫자를 생성하면서 값에 2를 곱하여 리스트 생성

print(c) 

#[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

TMI

리스트 컴프리헨션은 [식 for 변수 in 리스트]처럼 로 만들 수도 있고, list(식 for 변수 in 리스트)처럼 list로 만들 수도 있다.다. 둘 중에 성능은 대괄호 방식이 더 좋다. 특히 list 방식은 C 언어 스타일이라 대괄호 방식이 파이썬 다운 코드이다. 따라서 리스트 컴프리헨션은 대괄호 방식을 사용하는 것이 좋다.

리스트 컴프리헨션에서 if 조건문 사용하기

if 조건문은 for 반복문 뒤에 지정하여 사용한다.


a =  [i for i in range(10) if i % 2 == 0]
# 0~9 숫자 중 2의 배수인 숫자(짝수)로 리스트 생성

print(a)

# [0, 2, 4, 6, 8]

다음과 같이 for 반복문 뒤에 if 조건문을 지정하면 숫자를 생선한 뒤 if 조건문에서 특정 숫자만 뽑아내서 리스트를 생성한다.
다음 이미지를 보면 이해가 더 잘되것이다.

물론 다음과 같이 i를 다른 값과 연산해서 리스트를 만들 수도 있다.

b = [i + 5 for i in range(10) if i % 2 == 1]    
# 0~9 숫자 중 홀수에 5를 더하여 리스트 생성
print(b)
# [6, 8, 10, 12, 14]

for 반복문과 if 조건문을 여러 번 사용하기

다음과 같이 for와 if 를 여러번 사용할수도 있다.

[for 변수1 in 리스트1 if 조건식1     for 변수2 in 리스트2 if 조건식2     ...     for 변수n in 리스트n if 조건식n]

아래 예제코드는 2단부터 9단까지 구구단 리스트를 생성한다.


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

# [2, 4, 6, 8, 10, 12, 14, 16, 18, 3, 6, 9, 12, 15, 18, 21, 24, 27, 4, 8, 12, 16, 20, 24, 28, 32, 36, 5, 10, 15, 20, 25, 30, 35, 40, 45, 6, 12, 18, 24, 30, 36, 42, 48, 54, 7, 14, 21, 28, 35, 42, 49, 56, 63, 8, 16, 24, 32, 40, 48, 56, 64, 72, 9, 18, 27, 36, 45, 54, 63, 72, 81]

위에서는 코드를 한 줄로 입력했지만 다음과 같이 여러 줄로 입력해도된다. 이때 들여쓰기는 해도 되고 하지 않아도 된다. 하지만 가독성을 위해 들여쓰기를 해주는것이 좋다.


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

리스트 컴프리헨션에 for가 여러 개일 때 처리 순서는 뒤에서 앞으로 진행된다.

아래사진은 for가 여러 개일 때 처리 순서를 잘 설명해주는 사진이다.

Dictionary Comprehension

리스트로 만드는것이 아니라 딕셔너리로도 만들 수 있다.

dict = {i: i * i for i in range(10)}

print(dict)

# {0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}

Django에서 List Comprehension 쓰기

for문을 사용하였을때

def get(self, request):
        products      = Product.objects.all()
        product_list  = []
        for product in products:
            product_list.append(
                {
                    "english_name" : product.english_name,
                    "category"     : product.category.name,
                    "korean_name"  : product.korean_name,
                    "description"  : product.description,
                    "allergy"      : product.allergy,
                }
            )
        return JsonResponse({"data" : product_list}, status=200)

리스트 컴프리헨션을 사용하였을때

def get(self, request):
        products      = Product.objects.all()
        product_list  = 
        [
            {
                "english_name" : product.english_name,
                "category"     : product.category.name,
                "korean_name"  : product.korean_name,
                "description"  : product.description,
                "allergy"      : product.allergy,
            } 
        for product in products]
        return JsonResponse({"data" : product_list}, status=200)

Django에서도 깔끔하고, 가독성 높은 코드를 작성할 수 있다.

for문 vs list comprehension

for문을 사용해도 좋지만, 리스트 컴프리헨션을 사용할수 있을 때는
리스트 컴프리헨션을 사용해주는 것이 좋다.

  1. 더 파이써닉하다(파이썬을 파이썬 답게사용)
  2. mapping, filtering 때 유용하게 쓸 수 있다.
  3. 더 쉽게 읽히고 코드 가독성을 높힐 수 있다. for문은 list가 어떻게 만들어졌는지에 더 취중되어있다. 그러나 list comprehension은 list에 어떤 요소가 들어갈건지에 더 집중한다.

리스트 컴프리헨션의 장단점

장점

  • 간결하다.
  • 새로운 배열을 만들 때 유용하다.
  • for문보다 성능이 더 좋다. (실행속도가 빠르다.)

단점

  • 너무 복잡하게 작성할 경우 가독성이 떨어진다. 여러 줄의 표현식과 조건문으로 표현하는 게 나을 때도 있다.


. Reference
https://dojang.io/mod/page/view.php?id=2285
https://wikidocs.net/84393

profile
# 불편함을 편리함으로 바꾸고싶은 주니어 Back-end 개발자

1개의 댓글

comment-user-thumbnail
2021년 12월 19일

리스트 컴프리핸션 헷갈릴때마다 보러 올게요~!

답글 달기