서론
파이썬의 기초를 배우고 있는 사람이라면 아래와 같은 코드를 한번쯤 보았을 것이다.
반복문을 이용해 리스트를 만드는 방법으로, 대부분의 튜토리얼에서 이 방법을 먼저 선보이고 있는 것 같다.
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)를 한번 실행할 때마다 튜플을 순서대로 하나씩 돌려준다.
참고로 이터레이터는 리스트와 달리 한번 순회하고 나면 더이상 쓸 수가 없다.
마무리
간단하지만 상당히 유용한 내용이라 생각한다.
독자들께 도움이 되길 바란다.
'코딩 > Python' 카테고리의 다른 글
삼성인터넷(안드로이드) 업데이트 후 주피터노트북 커널 연결 오류 발생시 해결법 (0) | 2021.11.29 |
---|---|
회사에서 pip install 오류날 때(SSLCertVerificationError) (0) | 2021.11.26 |
파이썬 문자열 포맷팅 방법/f-string과 format 함수 (0) | 2021.11.26 |
스마트폰에서 주피터노트북(Jupyter notebook) 사용하는 방법/Pydroid 3, 태블릿, 안드로이드 (2) | 2021.11.18 |
스마트폰에서 파이썬(Python) 코딩하는 방법/Pydroid 3, 태블릿, 안드로이드 (4) | 2021.11.17 |
댓글