[03]Python - 리스트 컴프리헨션

김민지·2023년 8월 21일
3

Python

목록 보기
3/3

리스트 컴프리헨션

코딩 테스트 공부를 진행하면서 리스트 컴프리헨션이 정말 많이 사용된다는 사실을 알았다. 특히, 3줄 이상의 코드가 리스트 컴프리헨션을 사용하면 단 1줄로도 구현이 가능하다는 점이 흥미로웠다. 코드 길이를 축소하면서 훨씬 간결해지고 메모리 효율성이 좋기 때문에 코딩 테스트에서 자주 사용되는 것 같다.

이번 포스팅으로 리스트 컴프리헨션을 공부하고자 한다.

개념

  • 리스트 컴프리헨션(List Comprehension) 이란 'for문과 if문을 사용하여 리스트를 생성하는 방식으로, 한 줄로 리스트를 초기화하거나 변환할 수 있는 것'을 말한다.

일반적인 구문은 다음과 같다.

list1 = [expression for item in iterable]

list2 = [expression for item in iterable if condition]
  • expression: 표현식(변수명이 포함되어 있음)
  • item: 입력 iterable에서 가져온 각 항목(변수명)
  • iterable: 항목을 가져올 기존의 iterable 자료구조(리스트, 튜플, 문자열 등)
  • condition(선택): 필터링할 조건문

위처럼 for문만 사용하여 리스트를 생성할 수 도 있고, if문을 추가하여 필터링이 추가된 리스트를 생성할 수도 있다.

또한, 리스트 컴프리헨션이라고 해서 리스트만 사용할 수 있는 것이 아니라, 리스트(list), 튜플(tuple), 딕셔너리(dictionary), 세트(set)등 다양한 자료형도 모두 사용이 가능하다.

사용법

  • 위에서 정리한 개념과 예제 문제를 통해 리스트 컴프리헨션과 친해져 보자.

조건문(Condition) 없는 경우

  • 조건문을 주지 않는 경우, [expression for item in iterable] 형태로 작성하면 된다.

▶ 1부터 10까지 각 수를 제곱하고 모두 더한 값을 구하라.

# 기존 코드
list3 = [] # 빈 리스트 생성
for i in range(1, 11): # 숫자 1부터 10까지의 루프 생성
    list3.append(i*i) # 빈 리스트에 숫자의 제곱값 추가
    
total1 = sum(list3) # list3의 모든 원소 값을 더함

# 리스트 컴프리헨션 코드
total2 = sum([i*i for i in range(1, 11)]) # 기존 코드를 한 줄로 요약

print(f'기존 코드로 구한 값: {total1}')
print(f'리스트 컴프리헨션 코드로 구한 값: {total2}')
기존 코드로 구한 값: 385
리스트 컴프리헨션 코드로 구한 값: 385

이 예제를 보면 기존 코드는 4줄로 짜여있고, 리스트 컴프리헨션 코드는 단 한 줄로 짜여있는 것을 알 수 있다. 4줄로 짜여진 코드가 리스트 컴프리헨션 속에 어떻게 들어가 있는지 이해하는 것이 중요한 것 같다. 아래 링크를 참고하면 기존 코드와 리스트 컴프리헨션 코드를 비교하며 이해할 수 있다.
(참고: 리스트 컴프리헨션 - 제대로 파이썬)

리스트 컴프리헨션을 사용할 때, 조건(Condition)을 추가하여 필터링된 리스트를 생성할 수 있다. 조건문을 사용하는 경우 어떻게 표현하는지 알아보자!

조건문(Condition) 있는 경우

if 문

  • if문만 사용하는 경우, [expression for item in iterable if condition] 형태로 for문 뒤에 if문을 작성하면 된다.

▶ 주어진 숫자 리스트에서 홀수만 제곱값을 가지는 리스트를 생성하라.
numbers1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

# 기존 코드
numbers1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
list4 = [] # 빈 리스트 생성
for i in numbers1:
    if i % 2 != 0:
        list4.append(i**2) # 홀수 제곱값 리스트 생성
        
print(f'기존 코드로 구한 값: {list4}')
        
# 리스트 컴프리헨션 코드
numbers1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
squared_odd = [i**2 for i in numbers1 if i % 2 != 0] # 홀수인 숫자를 추려 제곱값을 구함
print(f'리스트 컴프리헨션 코드로 구한 값: {squared_odd}')
기존 코드로 구한 값: [1, 9, 25, 49, 81]
리스트 컴프리헨션 코드로 구한 값: [1, 9, 25, 49, 81]

▶ 주어진 문자열 리스트에서 길이가 5이하인 문자열만 대문자로 변환하여 리스트를 생성하라.
fruit = ['orange', 'banana', 'apple', 'grape', 'cherry']

# 기존 코드
fruit = ['orange', 'banana', 'apple', 'grape', 'cherry']
list5 = []
for i in fruit:
    if len(i) <= 5:
        list5.append(i.upper())

print(f'기존 코드로 구한 값: {list5}')
        
# 리스트 컴프리헨션 코드
fruit = ['orange', 'banana', 'apple', 'grape', 'cherry']
new_fruit = [i.upper() for i in fruit if len(i) <= 5]
print(f'리스트 컴프리헨션 코드로 구한 값: {new_fruit}')
기존 코드로 구한 값: ['APPLE', 'GRAPE']
리스트 컴프리헨션 코드로 구한 값: ['APPLE', 'GRAPE']

조건이 한 가지만 있는 경우, if문만 사용하여 필터링하면 된다.
이 경우에 리스트 컴프리헨션을 작성한다면, for문 다음에 if문을 작성해야 한다.

그렇다면, 조건이 두 가지인 경우는 어떻게 작성할까.?
for문 if문 else문 ?

if-else 문

  • if문만 사용하는 것과는 다르게 else문도 추가한다면, 작성 순서는 완전히 바뀐다.
  • if문만 사용할 때는 for문 오른쪽에 if문을 작성했다면, else문을 사용할 때는 for문 왼쪽에 if-else문을 작성한다.
  • 사용법은 다음과 같다.
    [expression_true if condition else expression_false for item in iterable]

▶ 주어진 숫자 리스트에서 홀수는 odd, 짝수는 even으로 분류하여 출력하라.
numbers2 = [15, 6, 489, 67, 4, 513, 48]

# 기존 코드
numbers2 = [15, 6, 489, 67, 4, 513, 48]
list6 = [] # odd와 even을 담을 빈 리스트 생성
for i in numbers2:
    if i % 2 != 0: # 홀수인 경우
        list6.append('odd')
    else: # 짝수인 경우
        list6.append('even')
        
print(f'기존 코드로 구한 값: {list6}')
        
# 리스트 컴프리헨션 코드
numbers2 = [15, 6, 489, 67, 4, 513, 48]
odd_even = ['odd' if i % 2 != 0 else 'even' for i in numbers2]
print(f'리스트 컴프리헨션 코드로 구한 값: {odd_even}')
기존 코드로 구한 값: ['odd', 'even', 'odd', 'odd', 'even', 'odd', 'even']
리스트 컴프리헨션 코드로 구한 값: ['odd', 'even', 'odd', 'odd', 'even', 'odd', 'even']

조건이 두 가지로 늘어나면서 기존 코드는 훨씬 더 길어진 것을 확인할 수 있다.
이 경우에 리스트 컴프리헨션을 사용하니까 코드의 간결성이 눈에 띄게 느껴진다.

그런데 조건문 중에 elif문도 있다. 리스트 컴프리헨션 코드에 elif문은 어떻게 표현할 수 있을까.?

elif 문

  • elif문은 조건을 더 추가하는 경우에 사용한다. 예를 들면, 숫자 리스트에서 0, 양수, 음수를 분류하는 문제에 elif문을 사용한다.
  • 기존 코드로 위 문제를 구현한다면 이렇게 구현될 것이다.
    if 0이면 0을 출력
    elif 짝수면 positive를 출력
    else 그 외엔 모두 negative를 출력
  • 리스트 컴프리헨션으로 이 문제를 구현한다면, elif를 사용하는 것이 아니라 if-else를 두 번 사용하여 구현해야 한다.
  • 사용법은 다음과 같다.
    [expression_if_condition1 if condition1 else expression_if_condition2 if condition2 else expression_if_condition3 for item in iterable]

▶ 주어진 숫자 리스트에서 0은 zero, 양수는 positive, 음수는 negative로 분류하여 출력하라.
numbers = [-1, 2, -3, 0, 4, -5]

# 기존 코드
numbers3 = [-1, 2, -3, 0, 4, -5]
list7 = [] # positive, negative, 0을 담을 빈 리스트 생성
for i in numbers3:
    if i > 0: # 양수인 경우
        list7.append('positive')
    elif i < 0: # 음수인 경우
        list7.append('negative')
    else: # 0인 경우
        list7.append('zero')
        
print(f'기존 코드로 구한 값: {list6}')

# 리스트 컴프리헨션 코드
numbers3 = [-1, 2, -3, 0, 4, -5]
classification = ['positive' if i > 0 else 'negative' if i < 0 else 'zero' for i in numbers3]
print(f'리스트 컴프리헨션 코드로 구한 값: {classification}')
기존 코드로 구한 값: ['odd', 'even', 'odd', 'odd', 'even', 'odd', 'even']
리스트 컴프리헨션 코드로 구한 값: ['negative', 'positive', 'negative', 'zero', 'positive', 'negative']

정리

  • 리스트 컴프리헨션이 작동하는 원리와 작성법에 대해 공부했다.
  • 조건문이 추가된 경우의 코드를 작성할 때 주어진 조건문에 따라 순서에 유의를 해야한다.
  • 리스트 컴프리헨션을 사용하면 코드를 간결하게 작성할 수 있고, 성능이 좋을 때가 많다.
  • 하지만, 너무 복잡하게 작성하면 코드의 가독성이 떨어질 수 있으므로 적절하게 사용하는 것이 중요하다.
profile
공부하고 기록하는 습관 들이는 중

0개의 댓글