본문 바로가기
코딩/Python

파이썬에서 코드 한줄로 리스트(딕셔너리, 집합, 제너레이터) 만들기/리스트컴프리헨션, list comprehension

by 나홀로코더 2021. 11. 26.
반응형

서론


파이썬의 기초를 배우고 있는 사람이라면 아래와 같은 코드를 한번쯤 보았을 것이다.

반복문을 이용해 리스트를 만드는 방법으로, 대부분의 튜토리얼에서 이 방법을 먼저 선보이고 있는 것 같다.

 

text = 'abc'
my_list = []
for i in text:
    my_list.append(i)


예제에서는 문자열 'abc'의 각 문자를 my_list라는 리스트에 담고 있는데, 그러기 위해서 먼저 빈 리스트를 my_list  변수로 선언한 뒤에, 문자열 'abc'의 각 문자를 순회하면서 list의 append 함수를 이용해 리스트에 더해주고 있다.

여기에서, 리스트에 담을 원데이터는 예제와 같은 문자열뿐만 아니라 무엇이든 될 수 있다.

리스트의 리스트, 데이터프레임의 리스트 등등 활용도는 무궁무진하다.

크게 어렵지 않고 이해하기도 편한 코드이긴 한데, 리스트 하나 만드는 데에 코드를 서너 줄이나 쓰려니 조금 번거롭게 느껴지기도 한다.

파이썬에서는 이러한 작업을 코드 한 줄로 간편하게 수행할 수 있는 리스트컴프리헨션(list comprehension) 기능을 지원하는데, 그 방법을 소개한다.

 

본론

 

1. 리스트컴프리헨션으로 리스트 만들기 기본


위 예제의 2번째 줄 이하는 아래와 같이 한 줄로 줄여 쓸 수 있다.

 

text = 'abc'
my_list = [i for i in text]


처음 보면 얼른 이해가 안 될 수도 있는데, 리스트 안쪽을 두 파트로 나누어서 보면 된다.

[  i          for i in text  ]

뒤쪽부터 이렇게 해석하면 된다.

2. text 안의 항목들 각각을 i라고 부르겠다. 그 i들에 대해서

1. i를 순서대로 리스트에 담아라.

 


이번에는 조금 변형해보자.

 

text = 'abc'
my_list = [i*5 for i in text]


i 대신 i*5를 썼으므로, 이번에는 이렇게 해석된다.

2. text 안의 항목들 각각을 i라고 부르겠다. 그 i들에 대해서

1. i에 5를 곱한 것을 순서대로 리스트에 담아라.

결과물인 my_list를 출력해보면 아래와 같은 리스트가 출력된다.

['aaaaa', 'bbbbb', 'ccccc']

여기에서는 *5만 해줬지만, 그밖에도 내가 원하는 데이터 형태로 얼마든지 변형해서 리스트에 담을 수가 있다.

 

 

2. for문을 두 번 사용하기


for문은 아래와 같이 중첩해서 사용할 수도 있다.

text_1 = 'abc'
text_2 = 'def'
my_list = []
for i in text_1:
    for j in text_2:
        my_list.append((i, j))


이 역시 리스트컴프리헨션을 이용해 간단하게 표현할 수 있다.

text_1 = 'abc'
text_2 = 'def'
my_list = [(i, j) for i in text_1 for j in text_2]


출력 결과는 아래와 같이 튜플의 리스트가 된다.

[('a', 'd'), ('a', 'e'), ('a', 'f'), ('b', 'd'), ('b', 'e'), ('b', 'f'), ('c', 'd'), ('c', 'e'), ('c', 'f')]

 

3. 조건문 추가하기


리스트컴프리헨션 구문에는 for문뿐만 아니라 if문도 추가할 수가 있다.

2번의 예제에서, f가 들어간 것들은 빼는 조건을 추가해보자.

text_1 = 'abc'
text_2 = 'def'
my_list = [(i, j) for i in text_1 for j in text_2 if j != 'f']


출력해보니 f가 들어간 것들은 빠지고 6개의 튜플만 리스트에 담겨 있다.

[('a', 'd'), ('a', 'e'), ('b', 'd'), ('b', 'e'), ('c', 'd'), ('c', 'e')]

 

 

4. 딕셔너리컴프리헨션, 제너레이터 표현식


간편하게 리스트를 만드는 방법을 보다 보니, for문을 이용해서 리스트만 만드는 것이 아니고 딕셔너리같은 것들도 만드는데, 그것도 이렇게 간단하게 만들 수 있는지 궁금해진다.

이 역시 가능하다.

먼저, 문자열 'abc'에 대해서 전체 문자열 내에서 각 문자의 위치를 키로, 그리고 각 문자를 값으로 하는 딕셔너리를 만들어보자.

text = 'abc'
my_list = {(i+1):j for i, j in enumerate(text)}


리스트를 의미하는 대괄호 대신 중괄호를 사용하고, "키:값" 형태로 변수를 넘겨주어 딕셔너리를 만들도록 하였다.

※ 문자열을 순회하면서 각 문자열의 위치(인덱스)까지 돌려주는 enumerate 함수를 사용

다음으로, 리스트 컴프리헨션에서 대괄호 대신 소괄호를 사용하면, 리스트 대신 이터레이터를 만들어준다.

3번의 예제에서 대괄호만 소괄호로 바꿔보자.

text_1 = 'abc'
text_2 = 'def'
my_iter = ((i, j) for i in text_1 for j in text_2)


이렇게 생성한 my_inter를 print해보면 <generator object <genexpr> at 0x6edf40fc80>라고만 나온다.

대신 next(my_iter)를 한번 실행할 때마다 튜플을 순서대로 하나씩 돌려준다.

참고로 이터레이터는 리스트와 달리 한번 순회하고 나면 더이상 쓸 수가 없다.

 

 

마무리

 

간단하지만 상당히 유용한 내용이라 생각한다.

 

독자들께 도움이 되길 바란다.

반응형

댓글