- 사람은 누구든지 "이름" = "홍길동", "생일" = "몇 월 며칠" 등으로 구별할 수 있다. 파이썬은 영리하게도 이러한 대응 관계를 나타낼 수 있는 자료형을 가지고 있다. 요즘 사용하는 대부분의 언어도 이러한 대응 관계를 나타내는 자료형을 갖고 있는데, 이를 연관 배열(Associative array) 또는 해시(Hash)라고 한다.
- 파이썬에서는 이러한 자료형을 딕셔너리(Dictionary)라고 하는데, 단어 그대로 해석하면 사전이라는 뜻이다. 즉 "people"이라는 단어에 "사람", "baseball"이라는 단어에 "야구"라는 뜻이 부합되듯이 딕셔너리는 Key와 Value를 한 쌍으로 갖는 자료형이다. 예컨대 Key가 "baseball"이라면 Value는 "야구"가 될 것이다.
- 딕셔너리는 리스트나 튜플처럼 순차적으로(sequential) 해당 요솟값을 구하지 않고 Key를 통해 Value를 얻는다. 이것이 바로 딕셔너리의 가장 큰 특징이다. baseball이라는 단어의 뜻을 찾기 위해 사전의 내용을 순차적으로 모두 검색하는 것이 아니라 baseball이라는 단어가 있는 곳만 펼쳐 보는 것이다.
dic = {'name':'pey', 'phone':'0119993323', 'birth': '1118'}
a = {'a': [1, 2, 3]}
-
기본적인 딕셔너리의 형태는 위와 같다. Key와 Value의 쌍 여러 개가 { }로 둘러싸여 있다. 각각의 요소는 Key : Value 형태로 이루어져 있고 쉼표(,)로 구분되어 있다.
- Key에는 변하지 않는 값을 사용하고, Value에는 변하는 값과 변하지 않는 값 모두 사용할 수 있다.
- 위에서 Key는 각각 'name', 'phone', 'birth'이고, 각각의 Key에 해당하는 Value는 'pey', '0119993323', '1118'이 된다.
-
또한, Value에는 리스트도 넣을 수 있다.
a = {1: 'a'}
a[2] = 'b'
print(a)
a['name'] = 'pey'
print(a)
{1: 'a', 2: 'b'}
{1: 'a', 2: 'b', 'name': 'pey'}
- {1: 'a'} 딕셔너리에 a[2] = 'b'와 같이 입력하면 딕셔너리 a에 Key와 Value가 각각 2와 'b'인 2 : 'b'라는 딕셔너리 쌍이 추가된다.
- 그 다음엔 딕셔너리 a에 'name': 'pey'라는 쌍을 추가해볼 수도 있다.
del a[1]
print(a)
{2: 'b', 'name': 'pey'}
- 딕셔너리의 요소를 삭제할 때는, del 함수를 사용해서 del a[key]처럼 입력하면 지정한 Key에 해당하는 {key : value} 쌍이 삭제된다.
grade = {'pey': 10, 'julliet': 99}
print(grade['pey'])
print(grade['julliet'])
10
99
- 위 예에서 'pey'라는 Key의 Value를 얻기 위해 grade['pey']를 사용한 것처럼 어떤 Key의 Value를 얻기 위해서는 딕셔너리변수이름[Key]를 사용한다.
- 딕셔너리는 리스트나 튜플에 있는 인덱싱 방법을 적용할 수 없다.
a = {1: 'a', 2: 'b'}
print(a[1])
print(a[2])
a
b
- 그래서 위의 경우처럼, a[1]이 인덱스가 아니라, a라는 딕셔너리의 1이라는 key를 의미하게 된다.
- 먼저 딕셔너리에서 Key는 고유한 값이므로 중복되는 Key 값을 설정해 놓으면 하나를 제외한 나머지 것들이 모두 무시된다는 점을 주의해야 한다.
a = {1: 'a', 1: 'b'}
print(a)
{1: 'b'}
- 이렇게 동일한 Key가 2개 존재할 경우 1:'a' 쌍이 무시된다.
a = {[1, 2]: 'hi'}
print(a)
TypeError: unhashable type: 'list'
b = {(1, 2): 'hi'}
print(b)
{(1, 2): 'hi'}
- 위와 같이 Key에 리스트는 쓸 수 없고 튜플은 Key로 쓸 수 있다. 딕셔너리의 Key로 쓸 수 있느냐 없느냐는 Key가 변하는(mutable) 값인지 변하지 않는(immutable) 값인지에 달려 있다. 따라서 리스트는 그 값이 변할 수 있기 때문에 Key로 쓸 수 없다.
a = {'name': 'pey', 'phone': '0119993323', 'birth': '1118'}
print(a.keys())
print(list(a.keys()))
dict_keys(['name', 'phone', 'birth'])
['name', 'phone', 'birth']
- keys()라는 함수를 딕셔너리 a에 사용하면, 딕셔너리 a의 Key만을 모아서 dict_keys라는 리스트 객체를 돌려준다.
- 여기에 list(a.keys()) 이렇게 list()를 붙여주면 dict_keys 객체를 리스트로 반환값을 받을 수 있다.
for k in a.keys():
print(k)
name
phone
birth
- dict_keys 객체는 위와 같이 사용할 수 있다. 다만, 리스트 고유의 append, insert, pop, remove, sort 함수는 수행할 수 없다.
a = {'name': 'pey', 'phone': '0119993323', 'birth': '1118'}
print(a.values())
print(list(a.values()))
dict_values(['pey', '0119993323', '1118'])
['pey', '0119993323', '1118']
- Key를 얻는 것과 마찬가지 방법으로 Value만 얻고 싶다면 values() 함수를 사용하면 된다. values 함수를 호출하면 dict_values 객체를 돌려준다.
- 여기에 list(a.values()) 이렇게 list()를 붙여주면 dict_values 객체를 리스트로 반환값을 받을 수 있다.
a = {'name': 'pey', 'phone': '0119993323', 'birth': '1118'}
print(a.items())
print(list(a.items()))
dict_items([('name', 'pey'), ('phone', '0119993323'), ('birth', '1118')])
[('name', 'pey'), ('phone', '0119993323'), ('birth', '1118')]
- items() 함수는 Key와 Value의 쌍을 튜플로 묶은 값을 dict_items 리스트 객체로 돌려준다.
- 마찬가지로 여기에 list(a.items()) 이렇게 list()를 붙여주면 dict_items 객체를 리스트로 반환값을 받을 수 있다.
a = {'name': 'pey', 'phone': '0119993323', 'birth': '1118'}
a.clear()
print(a)
{}
- clear() 함수는 딕셔너리 안의 모든 요소를 삭제한다. 빈 리스트를 [ ], 빈 튜플을 ( )로 표현하는 것과 마찬가지로 빈 딕셔너리도 { }로 표현한다.
a = {'name': 'pey', 'phone': '0119993323', 'birth': '1118'}
print(a.get('name'))
print(a.get('GANADARA'))
pey
None
- get(x) 함수는 x라는 Key에 대응되는 Value를 돌려준다. 앞에서 살펴보았듯이 a.get('name')은 a['name']을 사용했을 때와 동일한 결괏값을 돌려받는다.
- 다만, a['GANADARA']처럼 존재하지 않는 키로 값을 가져오려고 할 경우 a['GANADARA']는 Key 오류를 발생시키고 a.get('GANADARA')는 None을 돌려준다는 차이가 있다. 어떤것을 사용할지는 여러분의 선택이다.
a = {'name': 'pey', 'phone': '0119993323', 'birth': '1118'}
print(a.get('GANADARA', 'bar'))
bar
- 이렇게 딕셔너리 안에 찾으려는 Key 값이 없을 경우, 미리 정해 둔 디폴트 값을 대신 가져오게 하고 싶을 때에는 get(x, '디폴트 값')을 사용하면 편리하다.
a = {'name': 'pey', 'phone': '0119993323', 'birth': '1118'}
print('name' in a)
print('email' in a)
True
False
- 'name' 문자열은 a 딕셔너리의 Key 중 하나이다. 따라서 'name' in a를 호출하면 참(True)을 돌려준다. 반대로 'email'은 a 딕셔너리 안에 존재하지 않는 Key이므로 거짓(False)을 돌려준다.
- 집합(set)은 파이썬 2.3부터 지원하기 시작한 자료형으로, 집합에 관련된 것을 쉽게 처리하기 위해 만든 자료형이다.
s1 = set([1, 2, 3])
s2 = set("Hello")
print(s1)
print(s2)
{1, 2, 3}
{'l', 'o', 'H', 'e'}
- 위와 같이 set() 괄호 안에 리스트를 입력해서 집합을 만들거나 문자열을 입력해서 만들 수 있다.
-
그런데 위에서 살펴본 set("Hello")의 결과가 좀 이상하지 않은가? 분명 "Hello" 문자열로 set 자료형을 만들었는데 생성된 자료형에는 l 문자가 하나 빠져 있고 순서도 뒤죽박죽이다. 그 이유는 set에 다음과 같은 2가지 큰 특징이 있기 때문이다.
- 중복을 허용하지 않는다.
- 순서가 없다(Unordered).
- 중복을 허용하지 않는 set의 특징은 자료형의 중복을 제거하기 위한 필터 역할로 종종 사용하기도 한다.
-
리스트나 튜플은 순서가 있기(ordered) 때문에 인덱싱을 통해 자료형의 값을 얻을 수 있지만 set 자료형은 순서가 없기(unordered) 때문에 인덱싱으로 값을 얻을 수 없다.
- set 자료형을 정말 유용하게 사용하는 경우는 교집합, 합집합, 차집합을 구할 때이다.
s1 = set([1, 2, 3, 4, 5, 6])
s2 = set([4, 5, 6, 7, 8, 9])
print(s1)
print(s2)
{1, 2, 3, 4, 5, 6}
{4, 5, 6, 7, 8, 9}
- 위와 같이 s1, s2 집합이 있다고 가정하자.
s1 = set([1, 2, 3, 4, 5, 6])
s2 = set([4, 5, 6, 7, 8, 9])
print(s1 & s2)
print(s1.intersection(s2))
{4, 5, 6}
{4, 5, 6}
- 이렇게 & 기호나 intersection 함수를 사용하면 교집합을 구할 수 있다.
s1 = set([1, 2, 3, 4, 5, 6])
s2 = set([4, 5, 6, 7, 8, 9])
print(s1 | s2)
print(s1.union(s2))
{1, 2, 3, 4, 5, 6, 7, 8, 9}
{1, 2, 3, 4, 5, 6, 7, 8, 9}
- | 기호나 union 함수를 사용하면 합집합을 구할 수 있다.
s1 = set([1, 2, 3, 4, 5, 6])
s2 = set([4, 5, 6, 7, 8, 9])
print(s1 - s2)
print(s2 - s1)
print(s1.difference(s2))
print(s2.difference(s1))
{1, 2, 3}
{8, 9, 7}
{1, 2, 3}
{8, 9, 7}
- 그리고 빼기(-) 기호나 difference 함수를 사용하면 차집합을 구할 수 있다.
s1 = set([1, 2, 3])
s1.add(4)
print(s1)
{1, 2, 3, 4}
- 1개의 값만 집합에 추가할 때는 add 함수를 사용할 수 있다.
s1 = set([1, 2, 3])
s1.update([4, 5, 6])
print(s1)
{1, 2, 3, 4, 5, 6}
- 여러 개의 값을 한꺼번에 추가할 때는 update 함수를 사용할 수 있다.
s1 = set([1, 2, 3])
s1.remove(2)
print(s1)
{1, 3}
- 이렇게 특정 값을 제거하고 싶을 때는 remove 함수를 사용한다.
-
불(bool) 자료형이란 참(True)과 거짓(False)을 나타내는 자료형이다. 불 자료형은 다음 2가지 값만을 가질 수 있다.
- True - 참
- False - 거짓
-
True나 False는 파이썬의 예약어로 true, false와 같이 사용하지 말고 첫 문자를 항상 대문자로 사용해야 한다.
a = True
b = False
print(a)
print(b)
True
False
- 위와 같이 따옴표로 감싸지 않은 문자열을 변수에 지정해서 오류가 발생할 것 같지만 잘 실행된다.
- 자료형에 참과 거짓이 있다? 조금 이상하게 들리겠지만 참과 거짓은 분명히 있다. 자료형의 참과 거짓을 구분하는 기준은 위와 같다.
a = [1, 2, 3, 4]
while a:
print(a.pop())
4
3
2
1
- 다음과 같이 참과 거짓이 프로그램에 쓰이는 예시를 볼 수 있다.
- a.pop( ) 함수는 리스트 a의 마지막 요소를 끄집어내는 함수이므로 리스트 안에 요소가 존재하는 한(a가 참인 동안) 마지막 요소를 계속해서 끄집어낼 것이다. 결국 더 이상 끄집어낼 것이 없으면 a가 빈 리스트([ ])가 되어 거짓이 된다. 따라서 while문에서 조건이 거짓이 되므로 중지된다.
- 자료형에 참과 거짓이 있음을 이미 알아보았다. bool 내장 함수를 사용하면 자료형의 참과 거짓을 식별할 수 있다.
print(bool('python'))
print(bool(''))
print(bool(' '))
print(bool([1,2,3]))
print(bool([]))
print(bool(0))
print(bool(3))
True
False
True
True
False
False
True
- print(bool(' ')) 이 경우는 space 문자열로 인식되어 True가 된다.