for문
1. for문
반복문은 반복되는 작업을 효율적으로 처리할 수 있는 강력한 도구입니다. 이러한 반복문은 반복되는 여러 줄의 코드를 단 몇 줄로 실행할 수 있게 해줍니다.
도서관을 예로 들어 설명하겠습니다. 도서관에 3개의 책장이 있다고 가정하겠습니다. 1-1, 2-1, 3-1 책장이 있겠죠? 이걸 파이썬 코드로 출력한다면
print('1-1')
print('2-1')
print('3-1')
print('1-1')
print('2-1')
print('3-1')
이렇게 작성할 수 있습니다. 책장이 3개 밖에 안되서 하나하나 손으로 작성할 수 있지만, 만약 100개, 1000개라면 어떨까요? print('x-x')
를 100번, 1000번 수작업으로 반복해서 작성한다면 매우 힘들 것입니다. 이럴 때 사용하는 것이 바로 반복문입니다.
for i in range(1, 11) :
print(f'{i}-1')
for i in range(1, 11) :
print(f'{i}-1')
이렇게 반복문을 사용하면 코드를 간결하게 작성할 수 있습니다. 반복문은 크게 for문과 while문이 있습니다. for문은 정해진 횟수만큼 반복하고, while문은 조건이 참인 동안 반복합니다. 이번 챕터에서는 for문에 대해 다루도록 하겠습니다.
1.1. for문의 기본 구조
시퀀스 자료형 자료 또는 반복 가능한 자료형을 아래와 같이 순회 돌 수 있습니다.
for 변수명 in 순회_가능한_객체 :
pass # 수행할_문장
for 변수명 in 순회_가능한_객체 :
pass # 수행할_문장
for 키워드 다음에는 변수명
을 적습니다. 이 변수명은 앞에서 선언된 변수가 아니어야 합니다. in 키워드 다음에는 순회 가능한 객체
를 적습니다. 순회할 수 있는 객체는 리스트, 튜플, 문자열 등이 있습니다. 이렇게 순회 가능한 객체를 이터러블(Iterable)한 객체라고 합니다. 이터러블한 객체가 어떻게 하나의 항목을 순회 돌 수 있는지에 대해서는 클래스(class)에서 __iter__()
와 __next__()
를 직접 구현하며 다뤄봅니다. for 문의 끝에는 꼭 콜론(:
)을 붙여주어야 합니다. for문 아래에는 수행할 문장을 적습니다. 이때 수행할 문장은 들여쓰기를 해야 합니다. 들여쓰기를 하지 않으면 에러가 발생합니다.
for는 개별의 값을 변수에 할당하다가 순회할 값이 더이상 없는 경우 반복문을 종료시킵니다. 실제 반복문 내부에서는 순회할 값이 더이상 없을 때 StopIteration
예외가 발생하면서 반복문이 종료되는 것입니다. 이러한 이유로 for문은 순회할 수 있는 객체의 끝에 도달하면 반복을 멈추게 됩니다.
아래 예제는 시퀀스 자료형에 대표적인 문자열을 순회하는 방법입니다. 문자열 하나씩을 s라는 변수에 할당하여 반복하게 됩니다. 여기서 s는 변수 이름으로 다른 이름으로 변경해도 됩니다. 반복문에서는 i, j, k를 많이 사용합니다.
이 예제를 시각화하면 아래와 같습니다.
다른 예를 통해 for 문의 동작 원리를 좀 더 살펴보도록 하겠습니다. 아래 예제는 시퀀스형 자료형인 튜플을 반복하고 있습니다. x라는 변수로 튜플의 값을 하나씩 할당받아 for문 아래에 있는 문장을 반복하게 됩니다. 실행을 해보고 하나씩 주석을 풀고 실행해보세요. 위 그림처럼 직접 손으로 시각화 해보시는 것을 권해드립니다. 여기서 반복문의 범위는 들여쓰기로 구분합니다.
위 예제에서 튜플의 길이는 5이므로 for문은 반복을 5번 수행합니다.
순회 가능하다
라는 것은 어떤 의미일까요?
순회 가능한 객체의 범위는 인덱싱이 가능한 시퀀스 타입뿐만 아니라 더 넓습니다. 딕셔너리, 셋, 심지어 함수까지도 iter()와 next() 함수를 통해 순회가 가능합니다. 따라서 순서나 인덱스의 유무와 관계없이, iter()와 next()로 다음 값을 꺼낼 수 있는 모든 객체는 순회 가능한 객체라고 할 수 있습니다.
1.1.1 for문의 주의사항
반복문 앞에 선언한 변수명을 반복문의 변수로 선언하면 안됩니다. 그 이유는 for 문이 끝나더라도 해당 변수는 메모리에 남아 있기 때문입니다. 다음 예와 같이 실수에 주의해야 합니다.
위 코드에서 k가 100으로 남아 있기를 원했다면 그 다음 for 문에서 변수에 k를 사용하면 안됩니다. 코드를 실행해보면 k에는 100이 아니라 3이 할당이 되어 있는 것을 확인할 수 있습니다. 변수명을 바꿔서도 실행해보세요.
1.1.2 for문의 변수명
for와 같은 반복문을 사용할 때 i, j, k를 사용하는 것보다 아래와 같이 의미 있는 변수명을 사용하는 것이 좋습니다. 이렇게 하면 반복문이 길어지더라도 코드를 읽을 때 변수가 어떤 값을 가지고 있는지 쉽게 파악할 수 있습니다. 아래는 의미 파악이 쉽도록 'for 단수 in 복수'의 형태로 사용한 예제입니다.
다만 항상 이렇게 의미있는 변수를 사용하는 것은 아니고 실무에서도 간단한 코드의 경우 i, j, k 정도의 변수명은 허용하는 편입니다.
for book in books:
pass
for book in books:
pass
1.2 for문의 활용
for 문은 순회 가능한 자료형을 순회하며 각각의 요소를 꺼내볼 수 있습니다. 이처럼 순회 가능한 자료형은 문자열 자료형, 리스트 자료형, 딕셔너리 자료형, range로 지정하여 나눌 수 있습니다. 각 자료형에 따른 예를 살펴보고 어떤 차이점이 있는지 살펴봅시다.
1.2.1 문자열(str) 자료형을 범위로 지정한 예시
앞서 for 문의 원리를 살펴보고 문자열을 순회하며 실행되는 과정과 결과까지 알아봤습니다. 리스트, 튜플, 숫자 등 순회 가능한 여러 가지의 자료형이 있지만 실무에서 문자열을 순회하는 주된 이유는 특정한 문자가 있는지 검사하거나 문자열 모든 요소를 한번씩 출력하거나 문자열의 모든 요소를 덧셈 연산을 통해 연결하는 작업을 하기 위해서 입니다. 다음 예제를 살펴봅시다.
여기서 i는 문자열 '1', '2', '3'이 차례대로 들어가게 됩니다. 이 문자열을 내장 함수(Built-in Functions)인 int()
함수가 정수로 변환시켜 result에 더해주고 있으므로 result는 6이 됩니다.
이번에는 특수문자가 활용된 예제를 살펴보도록 하겠습니다. 사용자가 전화번호를 입력해야 하는데 하이픈을 잘못 입력하여 중간에 물음표가 입력되었습니다. 잘못 입력된 문자 때문에 에러가 생길 수 있으므로 사전에 에러를 방지하기 위해 특수문자를 모두 제거하는 코드를 작성해보도록 하겠습니다.
01010002000
01010002000
if 문에서 문자열을 하나씩 순회하면서 문자열이 숫자로 이루어져 있는지 확인하는 str.isdigit()
문자열 메서드로 체크합니다.
만약 조건문이 참이라면 result에 하나씩 더해줍니다. 여기서 result는 빈 문자열이며, i도 문자열이므로 i가 result에 연결됩니다. 그래서 for 반복문을 순회하며 빠져나오게 되며 return값은 01010002000이 나오게 됩니다.
1.2.2 리스트(list) 자료형을 범위로 지정한 예시
리스트 자료형은 순서가 있는 시퀀스 자료형으로 가변적인 특성을 가집니다. 리스트도 튜플과 동일하게 각 요소를 순회하면서 출력합니다.
이때 주의해야 할 점은 for문 안에서 리스트 길이가 변할 경우 오류가 발생하거나 무한 루프가 발생될 수 있습니다. 예를 들어 아래 코드는 무한 루프가 발생하는 코드입니다. 아래 코드는 실행시키지 마세요.
l = ['one', 'two', 'three']
for i in l:
l.append('four')
print(i)
l = ['one', 'two', 'three']
for i in l:
l.append('four')
print(i)
다음과 같이 리스트 안에 리스트가 중첩하여 있는 경우에는 묶여 있는 객체를 통으로 하나씩 순회합니다.
이 예제에서 i에 하나씩 들어가는 값은 [1, 2]와 [10, 20], [100, 200]이 순서대로 들어가게 됩니다. 첫 번째 print에서는 이 리스트를 그대로 출력하고 있습니다. 두 번째 print에서는 리스트인 i에서 i[0]와 i[1] 값을 더한 값을 출력합니다.
이는 다음과 같은 코드로 변경할 수 있습니다.
순회하는 값이 리스트인 [a, b]의 형태이기 때문에 이를 각각 i와 j라는 변수에 할당하겠다는 것입니다. 위의 코드와는 for 다음에 나오는 변수를 i,j로 변경하여 각 서브리스트의 요소를 i, j 에 할당하여 출력할 수 있도록 바꿨습니다. 이렇게 바꿈으로써 이전 코드에서는 각 서브리스트 요소, 리스트의 합을 출력한 반면에 위의 코드는 서브리스트의 요소를 변수에 할당한 차이점이 있지만 동일한 결괏값이 나옵니다. 이렇게 순회할 수 있는 객체를 변수에 하나씩 할당하는 것을 언패킹(Unpacking)
이라고 합니다. 언패킹은 함수 챕터에서 더 자세히 다루도록 하겠습니다.
1.2.3 사전(dict) 자료형을 범위로 지정한 예시
for 문을 이용하여 딕셔너리 자료형을 순회하면 키(Key)만 가져오게 됩니다. 아래 코드를 실행시켜보세요.
위 코드에 단어_사전
은 키
와 값
의 쌍으로 이뤄진 딕셔너리 자료형입니다. for문은 이 자료형을 순회하며 키값만을 가져옵니다. 따라서 출력 결과는 하나, 둘, 셋이 됩니다.
키
에 해당하는 값
또한 가져오고 싶다면 아래와 같이 언패킹을 사용할 수 있습니다.
튜플 언패킹 외에도 딕셔너리의 키를 순회하면서 각 키에 해당하는 값을 출력할 수 있습니다.
1.2.4 range를 범위로 지정한 예시
for문에서 가장 많이 사용되는 range에 대해 알아봅시다. range는 앞 챕터 내장함수(built-in function)에서 다뤄봤습니다. range(시작_값, 종료_값, 연속하는_두_수의_차)
형식입니다.
가장 많이 사용되는 형태는 range(n)
의 형태입니다.
range는 하나씩 꺼낼 때마다 값이 생성이 되는 것이기 때문에 0이 i값에 할당이 될 때에는 1값을 아직 생성하지 않은 상태입니다. 0부터 4까지 모두 생성해놓고 반복이 된다고 생각하시면 안됩니다.
아래 코드는 0 이상, 10 이하 짝수만 더하는 코드입니다. 10 이하이기 때문에 range의 종료값이 11이어야 합니다. 종료값-1
까지 값을 생성하기 때문입니다.
아래 코드는 1부터 100까지 더하는 코드입니다.
이러한 코드는 아래 코드보다 성능이 떨어집니다. 위 코드는 100번 순회를 돌아야 하는데 아래 코드는 한 번만 수행하면 되기 때문입니다.
이번에는 1부터 100까지 짝수를 모두 더하는 코드를 작성해보도록 하겠습니다. 우선 비효율적인 코드입니다. 이 코드는 0부터 100까지 짝수를 더하는 코드입니다. 100번 순회를 돌고, if문도 확인해야 합니다.
이 코드는 절반만 순회를 돌고, if문도 확인할 필요가 없어 위 코드에 비해 효율적입니다.
2. 중첩 for문
중첩 반복문은 하나의 반복문 안에 다른 반복문을 포함시키는 것을 의미합니다. 중첩 반복문을 사용하여 더 복잡한 패턴을 생성하고, 다양한 조건을 만족하는 데이터를 검색하거나 처리할 수 있습니다.
처음 예제를 들었던 도서관에 대해 다시 한 번 생각해보도록 하겠습니다. 도서관에는 3개의 책장이 있었습니다. 각 책장에는 10권의 책이 있습니다. 이를 표현하자면 아래와 같습니다.
1-1, 1-2, 1-3...
2-1, 2-2, 2-3...
3-1, 3-2, 3-3...
1-1, 1-2, 1-3...
2-1, 2-2, 2-3...
3-1, 3-2, 3-3...
이것을 코드로 작성하여 표현하려면 어떻게 해야 할까요? 첫번째 예시로 들었던 것과 달리 증가되는 부분이 2곳이 있습니다. 하나는 층이 증가할 때, 다른 하나는 책이 증가할 때입니다. 이렇게 증가하는 부분이 2곳이 있을 때에는 중첩 반복문을 사용할 수 있습니다.
중첩 반복문에서 주의할 점
중첩 반복문을 사용할 때는 변수명이 겹치지 않도록 주의해야 합니다. 변수명을 중복해서 사용할 경우 가장 최근 반복문을 기준으로 변수값이 정해지기 때문에 의도하지 않은 결과가 나올 수 있으므로 변수명을 확인해야 합니다.
중첩 반복문의 또 다른 예로 앞에서 다뤄본 리스트 안에 리스트 예제를 다시 한 번 보도록 하겠습니다. 이번에는 언패킹을 하지 않고 하나의 변수에서 확인을 하였습니다.
# 1
에서 i는 리스트를 하나씩 받으므로 또다시 순회를 할 수 있습니다. 예를 들어 첫 값인 [1, 2]를 받았을 때에는 다음 코드와 같이 순회할 수 있습니다.
위 코드의 변수는 의도적으로 j로 할당했습니다. 이 코드를 # 1
의 코드와 합치도록 하겠습니다. # 1
바로 아래 print(i)가 있던 자리에 # 2
을 넣으면 다음과 같은 형태가 될 것입니다.
다만 우리는 좀 더 직관적인 출력 결과를 보기 위해 print를 하나 더 추가하도록 하겠습니다.
[1, 2]
1
[1, 2]
2
[10, 20]
10
[10, 20]
20
[100, 200]
100
[100, 200]
200
[1, 2]
1
[1, 2]
2
[10, 20]
10
[10, 20]
20
[100, 200]
100
[100, 200]
200
출력 결과를 보면 어떤 값을 순회하고 있는지도 확인을 할 수 있습니다. 이처럼 순회하고자 하는 값에 또 다시 순회를 하고 싶을 때에는 중첩 반복문을 사용합니다.
중첩된 반복문은 for 문이 여러 개라 순회하는 루틴이 헷갈릴 수 있으며 처음에 이해하기 어려울 수 있습니다. 따라서 다음 코드에서 사용된 변수 i 값과 j 값, 출력 결과를 한 step씩 따라가보길 권해드립니다. 순회가 1번 이뤄질 때마다 각각 i 와 j 값이 어떻게 나오는지 손으로 써보시길 바랍니다. 지루한 작업이지만 이 작업을 통해 for 문을 좀 더 친숙하게 느끼실 수 있을 것입니다.
이번에는 중첩 for 문을 사용하여 구구단을 출력해보도록 하겠습니다. 실행해보세요.
# 1
for 문에서 range( ) 함수를 이용하여 2부터 9(stop-1)까지 차례로 i 에 넣어줍니다. i 는 첫 번째 for 문의 '단'으로 나옵니다. # 2
for 문에서 # 1
에서 할당된 i 에 곱해지는 수를 j 에 넣고 구구단을 출력하고 있습니다. 2단에서 9까지 들어간 return값이 나온 이후 두 번째 for 문이 종료됨과 동시에 첫 번째 for 문으로 넘어와 3단으로 넘어가고 두 번째 for 문으로 들어와 j 의 값이 다시 1 부터 시작하여 마지막까지 돈 후 반복문을 빠져나오게 됩니다.
3. 컴프리헨션(comprehension)
컴프리헨션은 파이썬의 자료구조(list, dictionary, set)에 데이터를 좀 더 쉽고 간결하게 담기 위한 문법입니다. 여기서 말하는 '쉽고 간결하게' 데이터를 담는 방법이란 반복문과 조건문을 결합하여 하나의 구문으로 만들어 담는 것을 의미합니다. 또한 컴프리헨션 문법은 일반 반복문(루프)을 사용하는 것보다 빠릅니다. 이는 파이썬에 내부 구현이 최적화가 되어 있기 때문입니다. 컴프리헨션은 리스트 컴프리헨션, 딕셔너리 컴프리헨션 등이 있습니다. 여기서는 형태가 비슷한 것을 제외하고 리스트 컴프리헨션과 딕셔너리 컴프리헨션에 대해 다루도록 하겠습니다.
3.1. 리스트 컴프리헨션(list comprehension)
3.1.1. 리스트 컴프리헨션 기본 사용법
리스트 컴프리헨션(List comprehension)은 파이썬에서 반복문을 사용하여 리스트를 간결하게 생성하는 방법입니다. 리스트 컴프리헨션을 사용하면 좀 더 편리하고 직관적인 프로그램을 만들 수 있습니다. 실무에서도 자주 사용하는 코드이니 꼭 기억해주시기 바랍니다. 다만, 컴프리헨션 문법은 복잡도가 올라가면 루프를 만들어 가독성을 올리는 것을 권합니다.
이러한 문법은 아래와 같이 간결하게 만들 수 있습니다.
# step1 list안에 for문을 가져옵니다.
[for i in range(1, 10)]
# step2 append 항목을 맨 앞으로 가져옵니다.
a = [i for i in range(1, 10)] # 출력: [1, 2, 3, 4, 5, 6, 7, 8, 9]
b = [i*2 for i in range(1, 10)] # 출력: [1, 2, 3, 4, 5, 6, 7, 8, 9]
# step1 list안에 for문을 가져옵니다.
[for i in range(1, 10)]
# step2 append 항목을 맨 앞으로 가져옵니다.
a = [i for i in range(1, 10)] # 출력: [1, 2, 3, 4, 5, 6, 7, 8, 9]
b = [i*2 for i in range(1, 10)] # 출력: [1, 2, 3, 4, 5, 6, 7, 8, 9]
이러한 컴프리헨션 문법은 간결함을 증대시킬 뿐만 아니라 기존 반복문으로 리스트에 값을 추가(append)하는 것보다 속도가 빠릅니다.
기본적인 형태는 아래와 같습니다.
[추가할_변수_또는_표현식 for 변수명 in 순회_할_수_있는_객체]
[추가할_변수_또는_표현식 for 변수명 in 순회_할_수_있는_객체]
아래 코드로 간단하게 컴프리헨션을 실습해보세요.
3.1.2. 컴프리헨션 내 조건문 사용법
리스트 컴프리헨션 안에 조건문을 사용해 봅시다. 리스트 컴프리헨션의 조건문 문법은 다음과 같습니다.
[표현식 for 항목 in 반복_가능_객체 if 조건문]
[표현식 for 항목 in 반복_가능_객체 if 조건문]
아래 코드는 3과 5의 배수를 리스트에 담는 코드입니다. 이 코드를 컴프리헨션으로 바꾸어보도록 하겠습니다.
아래 코드는 위 코드를 컴프리헨션으로 바꾼 것입니다. 이 코드를 실행해보세요.
단계별로 하나씩 살펴보도록 하겠습니다.
# step1 for문을 가져옵니다.
l = [for i in range(1, 100)]
# step2 append 항목을 맨 앞으로 가져옵니다.
l = [i for i in range(1, 100)]
# step3 if문을 추가합니다.
l = [i for i in range(1, 100) if i % 3 == 0 or i % 5 == 0]
# step1 for문을 가져옵니다.
l = [for i in range(1, 100)]
# step2 append 항목을 맨 앞으로 가져옵니다.
l = [i for i in range(1, 100)]
# step3 if문을 추가합니다.
l = [i for i in range(1, 100) if i % 3 == 0 or i % 5 == 0]
컴프리헨션에서 if와 함께 else를 사용하고 싶다면 아래와 같이 앞 부분에 배치하여 사용할 수 있습니다.
이렇게 if 문이 단독으로 쓰일 때에는 for 문 뒤에, if 문과 else 문이 함께 쓰일 때에는 for 문 앞에 온다는 사실을 기억해 주시기 바랍니다.
다만 위 코드는 좋은 코드가 아닙니다. 위 코드는 이미 79자를 넘겨 가독성이 떨어진 상태입니다. 이렇게 가독성이 떨어질 때에는 아래와 같이 사용하시는 것을 권합니다. 복잡한 것은 가독성을 떨어트립니다. 가독성이 떨어지면 코드를 이해하는데 시간이 더 걸리게 됩니다. 꼭 한 줄에 모든 것을 다 쓸 필요는 없습니다. 누가 읽어도 자연스럽게 읽혀질 수 있도록 코드를 작성해주세요.
아래처럼 중첩된 if를 사용할 수 있습니다.
위 코드는 아래와 같은 의미를 지닙니다.
3.1.3. 중첩된 반복문과 중첩된 컴프리헨션
리스트 컴프리헨션 안에 중첩된 반복문을 사용할 수 있고 리스트 컴프리헨션 자체의 중첩할 수도 있습니다. 다음 코드를 통해 여러 형태의 리스트 컴프리헨션을 익혀봅시다. 다만 이보다 더 복잡한 형태의 컴프리헨션은 가독성을 위해 권하지 않습니다. 다음 코드를 통해 어떤 원리로 작동하는지 알아봅시다.
# 일반적인 사용 방법
c_list = []
for i in range(2, 10): # 1
for j in range(1, 10): # 2
c_list.append(f'{i} × {j} = {i*j}') # 3
# 일반적인 사용 방법
c_list = []
for i in range(2, 10): # 1
for j in range(1, 10): # 2
c_list.append(f'{i} × {j} = {i*j}') # 3
먼저 위코드를 리스트 컴프리헨션으로 만들기 위해 # 1
코드와 # 2
코드를 아래와 같이 리스트 안에 넣습니다. 여기서 주의깊게 보셔야 할 부분은 # 1
안에 # 2
가 있다는 점입니다.
[for i in range(2, 10) for j in range(1, 10)]
[for i in range(2, 10) for j in range(1, 10)]
이제 표현할 코드인 # 3
을 리스트 컴프리헨션 맨 앞에 둡니다.
최종적으로 위와 같은 코드가 됩니다. 위와 같은 코드는 다음과 같이 중첩된 컴프리헨션으로 표현할 수도 있습니다. 이 코드는 중첩된 리스트를 생성합니다. 순서에 유의하여 다음 코드를 봐주시길 바랍니다.
중첩 컴프리헨션은 기존 컴프리헨션의 중첩된 반복문과 for 문의 순서가 다릅니다. 위 코드는 j 가 먼저 나오는 반면, 기존 중첩된 반복문의 컴프리헨션은 i 가 먼저 나옵니다. 밖에서부터 안쪽으로 계산됩니다.
이러한 컴프리헨션 문법의 중첩은 복잡도가 증가하게 되면 코드의 가독성을 떨어트리므로 주의해 사용해주세요. 보통 회사 컨벤션(회사의 코딩 규칙)에서는 3개 이상의 컴프리헨션 중첩을 하지 않기를 권합니다.
3.1.4. 컴프리헨션 내 함수 사용하기
기존 리스트를 순회하며 요소들을 함수의 인수에 넣어 함수의 return 값을 새로운 리스트에 저장할 수 있습니다.
먼저 # 1
에서 i를 100으로 나눴을 때 딱 떨어지면 기존 값을 return 하고 나머지가 있으면 0을 return 하는 함수 sumthingFunction()
을 만들었습니다. # 2
에서 주어진 리스트 l의 각각의 값이 # 3
리스트 컴프리헨션 안의 함수 sumthingFunction()
을 거쳐 l에 새로운 값으로 저장됩니다. 따라서 출력값은 [100, 200, 300, 0, 0, 0]이 나오게 됩니다.
3.2. 딕셔너리 컴프리헨션
딕셔너리 컴프리헨션 또한 기본적인 사용법은 리스트 컴프리헨션과 동일합니다. 다만 딕셔너리 자체가 키:값
으로 이루어진 형태인 만큼 약간의 차이가 있습니다. 딕셔너리 컴프리헨션의 기본 구조는 중괄호({}
) 내부에 for문과 필요한 조건문을 넣어주며, 그 앞에는 딕셔너리의 키와 값이 콜론(:
)으로 구분되어 위치합니다. 그럼 딕셔너리 컴프리헨션은 어떤 것인지 살펴봅시다.
# 전통적인 방법
d = {}
for i in range(5):
d[i] = i**2
# 전통적인 방법
d = {}
for i in range(5):
d[i] = i**2
위 코드는 딕셔너리 d를 선언하고 키에 0, 1, 2, 3, 4를 차례대로 넣고 그에 대응하는 값은 키의 제곱을 한 값으로 할당하였습니다. result 값은 {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
이 나옵니다.
그럼 딕셔너리 컴프리헨션으로 바꾸면 어떻게 되는지 봅시다. 만드는 순서는 리스트 컴프리헨션과 동일합니다. 우선 콜론을 빼고 for 문을 중괄호 안으로 가져옵니다.
{for i in range(5)}
{for i in range(5)}
이제 맨 앞에 추가시킬 요소를 넣습니다. for 문 앞으로 가져올 때 키: 값
형태인 쌍으로 가져와야 합니다.
{i: i**2 for i in range(5)}
{i: i**2 for i in range(5)}
딕셔너리 컴프리헨션도 리스트 컴프리헨션과 마찬가지로 if 문을 사용할 수 있습니다.
4. 복합 자료형 순회
딕셔너리 자료형에서 다뤘던 것처럼 반복되는 값이 같은 구조를 가지고 있다면 언패킹하여 한꺼번에 받아 순회할 수 있습니다. 순회할 수 있는 객체를 변수에 하나씩 할당하는 것을 언패킹이라 하였습니다. 이번에는 리스트 안에 리스트가 아니라 리스트 안에 문자열, 리스트 안에 튜플 등 다양한 복합 자료형이 중첩되어 있을 때 어떻게 언패킹하여 순회를 하는지 다뤄보겠습니다.
리스트 안에 문자열이 들어간다면 해당 자료형도 언패킹할 수 있습니다. 문자열은 순회할 수 있는 객체이기 때문입니다. 따라서 처음 순회가 될 ‘abc’가 준비되었을 때 전체를 받을 변수 하나가 있다면 하나의 변수에 할당이 되며, 'a', 'b', 'c' 각각의 값을 받을 변수가 모두 준비되어 있다면 이를 각각의 변수에 할당합니다.
'skills'라는 리스트에 2개의 요소를 가진 튜플이 연속하여 들어있는 자료형이 있습니다. 첫 번째 요소는 skill의 이름을 나타내고 두 번째 요소는 스킬의 마나(소비량)을 나타냅니다. skill을 순회하면서 각 튜플을 하나씩 가져와서 i, j에 저장한 후 출력합니다. 위 코드를 실행해보세요.
5. enumerate를 사용한 순회
enumerate는 순회 가능한 객체에 순서를 매길 때 사용합니다. enumerate는 별도의 변수를 선언하지 않고 순서를 매길 수 있습니다. enumerate는 인덱스와 값을 함께 반환합니다. enumerate는 다음과 같은 형태로 사용합니다.
enumerate(순회 가능한 객체, 인덱스의 시작값)
enumerate(순회 가능한 객체, 인덱스의 시작값)
enumerate에 인덱스의 시작값을 지정하지 않으면 기본값 0부터 시작하는 것을 볼 수 있습니다.
만약 시작값을 100으로 설정하면 100부터 하나씩 증가하면서 인덱스를 생성합니다. 수치를 변경해가며 실행해보세요.
이를 아래와 같이 표현하는 것은 파이써닉하지 않다고 얘기합니다. 파이썬에서는 이러한 코드를 지양합니다.
만약 인덱스만 필요하다면 아래와 같이 사용할 수 있습니다.
6. for 문으로 무한반복 만들기
일반적으로 for문으로 일부러 무한반복을 만들 일은 없습니다. 다음과 같은 코드를 짜지 않도록 주의해야 합니다.