12.1 딕셔너리 만들기

Unit 12. 딕셔너리 사용하기

지금까지 살펴봤던 리스트와 튜플은 값 여러 개를 일렬로 저장할 뿐 값끼리 연관 관계가 없었습니다. 예를 들어 게임 캐릭터의 능력치를 리스트에 저장해보겠습니다.

lux = [490, 334, 550, 18.72]

리스트 lux에서 인덱스 0은 체력, 인덱스 1은 마나, 인덱스 2는 사거리, 인덱스 3은 방어력이라고 했을 때 리스트만 봐서는 각 값이 어떤 능력치인지 쉽게 알기가 힘듭니다.

파이썬에서는 연관된 값을 묶어서 저장하는 용도로 딕셔너리라는 자료형을 제공합니다. 그럼 게임 캐릭터의 능력치를 딕셔너리에 저장해보겠습니다.

lux = {'health': 490, 'mana': 334, 'melee': 550, 'armor': 18.72}

이제 딕셔너리만 봐도 lux라는 캐릭터의 체력(health)은 490, 마나(mana)는 334, 사거리(melee)는 550, 방어력(armor)은 18.72라는 것을 쉽게 알 수 있습니다. 이처럼 딕셔너리는 값마다 이름을 붙여서 저장하는 방식입니다.

즉, 사전(dictionary)에서 단어를 찾듯이 값을 가져올 수 있다고 하여 딕셔너리라고 부릅니다.

이번 유닛부터 딕셔너리를 만드는 방법과 기본 사용 방법을 알아보겠습니다.

12.1 딕셔너리 만들기

딕셔너리는 { }(중괄호) 안에 키: 값 형식으로 저장하며 각 키와 값은 ,(콤마)로 구분해줍니다.

  • 딕셔너리 = {키1: 값1, 키2: 값2}

그럼 키와 값이 4개씩 들어있는 딕셔너리를 만들어보겠습니다.

>>> lux = {'health': 490, 'mana': 334, 'melee': 550, 'armor': 18.72}
>>> lux
{'health': 490, 'mana': 334, 'melee': 550, 'armor': 18.72}
에러

SyntaxError: invalid syntax: { }의 짝이 맞지 않을 때, 키:값 형식에 맞지 않을 때, 키 문자열의 ' ' 짝이 맞지 않을 때, 각 키:값을 구분할 때 ,를 넣지 않아서 발생하는 구문 에러입니다. { }, ' ' 짝이 맞는지, 키:값 형식에 맞는지, ,를 빠뜨리지 않았는지 확인해주세요.

딕셔너리는 키를 먼저 지정하고 :(콜론)을 붙여서 값을 표현합니다. 특히 키에는 값을 하나만 지정할 수 있으며 이런 특성을 따서 키-값 쌍(key-value pair)이라 부릅니다(키-값은 1:1 대응).

12.1.1  키 이름이 중복되면?

그럼 딕셔너리를 만들 때 키 이름이 중복되면 어떻게 될까요? (파이썬 3.6 기준)

>>> lux = {'health': 490, 'health': 800, 'mana': 334, 'melee': 550, 'armor': 18.72}
>>> lux['health']    # 키가 중복되면 가장 뒤에 있는 값만 사용함
800
>>> lux    # 중복되는 키는 저장되지 않음
{'health': 800, 'mana': 334, 'melee': 550, 'armor': 18.72}

딕셔너리 lux를 만들 때 'health': 490이 있고 그 뒤에 'health': 800을 넣었습니다. 즉, 키 'health'가 중복됩니다. 이 상태에서 lux['health']를 출력해보면 800이 나옵니다. 즉, 딕셔너리에 키와 값을 저장할 때 키가 중복되면 가장 뒤에 있는 값만 사용합니다. 따라서 중복되는 키는 저장되지 않습니다.

12.1.2  딕셔너리 키의 자료형

딕셔너리의 키는 문자열뿐만 아니라 정수, 실수, 불도 사용할 수 있으며 자료형을 섞어서 사용해도 됩니다. 그리고 값에는 리스트, 딕셔너리 등을 포함하여 모든 자료형을 사용할 수 있습니다.

>>> x = {100: 'hundred', False: 0, 3.5: [3.5, 3.5]}
>>> x
{100: 'hundred', False: 0, 3.5: [3.5, 3.5]}

단, 키에는 리스트와 딕셔너리를 사용할 수 없습니다.

>>> x = {[10, 20]: 100}
Traceback (most recent call last):
  File "<pyshell#3>", line 1, in <module>
    x = {[10, 20]: 100}
TypeError: unhashable type: 'list'
>>> x = {{'a': 10}: 100}
Traceback (most recent call last):
  File "<pyshell#4>", line 1, in <module>
    x = {{'a': 10}: 100}
TypeError: unhashable type: 'dict'

12.1.3  빈 딕셔너리 만들기

빈 딕셔너리를 만들 때는 { }만 지정하거나 dict를 사용하면 됩니다. 보통은 { }를 주로 사용합니다.

  • 딕셔너리 = {}
  • 딕셔너리 = dict()
>>> x = {}
>>> x
{}
>>> y = dict()
>>> y
{}

12.1.4  dict로 딕셔너리 만들기

dict는 다음과 같이 키와 값을 연결하거나, 리스트, 튜플, 딕셔너리로 딕셔너리를 만들 때 사용합니다.

  • 딕셔너리 = dict(키1=값2, 키2=값2)
  • 딕셔너리 = dict(zip([키1, 키2], [값1, 값2]))
  • 딕셔너리 = dict([(키1, 값1), (키2, 값2)])
  • 딕셔너리 = dict({키2: 값1, 키2: 값2})

먼저 다음과 같이 dict에서 키=값 형식으로 딕셔너리를 만들 수 있습니다. 이때는 키에 ' '(작은따옴표)나 " "(큰따옴표)를 사용하지 않아야 합니다. 키는 딕셔너리를 만들고 나면 문자열로 바뀝니다.

>>> lux1 = dict(health=490, mana=334, melee=550, armor=18.72)    # 키=값 형식으로 딕셔너리를 만듦
>>> lux1
{'health': 490, 'mana': 334, 'melee': 550, 'armor': 18.72}

두 번째 방법은 dict에서 zip 함수를 이용하는 방법입니다. 다음과 같이 키가 들어있는 리스트와 값이 들어있는 리스트를 차례대로 zip에 넣은 뒤 다시 dict에 넣어주면 됩니다(zip'47.5 내장 함수'를 참조해주세요).

>>> lux2 = dict(zip(['health', 'mana', 'melee', 'armor'], [490, 334, 550, 18.72]))    # zip 함수로
>>> lux2                                                            # 키 리스트와 값 리스트를 묶음
{'health': 490, 'mana': 334, 'melee': 550, 'armor': 18.72}

물론 키와 값을 리스트가 아닌 튜플에 저장해서 zip에 넣어도 됩니다.

세 번째 방법은 리스트 안에 (키, 값) 형식의 튜플을 나열하는 방법입니다.

>>> lux3 = dict([('health', 490), ('mana', 334), ('melee', 550), ('armor', 18.72)])
>>> lux3                                                  # (키, 값) 형식의 튜플로 딕셔너리를 만듦
{'health': 490, 'mana': 334, 'melee': 550, 'armor': 18.72} 

네 번째 방법은 dict 안에서 중괄호로 딕셔너리를 생성하는 방법입니다.

>>> lux4 = dict({'health': 490, 'mana': 334, 'melee': 550, 'armor': 18.72})     # dict 안에서
>>> lux4                                                           # 중괄호로 딕셔너리를 만듦
{'health': 490, 'mana': 334, 'melee': 550, 'armor': 18.72}

이처럼 딕셔너리는 키를 통해서 값의 의미를 파악하기 쉽습니다. 특히 딕셔너리는 예제의 게임 캐릭터 능력치처럼 특정 주제에 대해 연관된 값들을 모아둘 때 주로 사용합니다.