파이썬을 배워보자 6일차 - 딕셔너리

0

Python

목록 보기
6/18

점프 투 파이썬 : https://wikidocs.net/book/1
파이썬 기본을 갈고 닦자 : https://wikidocs.net/16031

Dictionary

딕셔너리는 내부적으로 해시테이블로 구현되어있어, key-value 쌍으로 데이터를 저장하고 사용할 수 있다.

key는 하나의 열쇠다. value가 그 열쇠로 접근할 수 있는 방, 또는 물건이 되는 것이다.

즉, 여태까지는 번호로 물건을 찾았다면 이제는 이름으로 물건을 찾을 수 있다는 것이다. 때문에 딕셔너리는 순차적이지 않다. key는 어떤 key값을 넣냐에 따라 달라지기 때문이다.

1. 딕셔너리 만들기

  • {}, dict()을 사용하여 만들 수 있다.
  • 키는 불변이되, 값은 가변적이다.
  • 비순서적이기 때문에 번호로 접근할 수 없고, 순서가 의미가 없다.

기본적인 모습은 다음과 같다.

a = {'key' : value}
a = dict()

값으로 이거저거 다 넣을 수 있다.

a = {'list': [1,2,3], 'tuple': (1,2,3), 'number': 2 , 'string':"hello"}
print(a['list'] , a['tuple'], a['number'] , a['string']) # [1, 2, 3] (1, 2, 3) 2 hello

다음과 같이 리스트, 튜플, 정수, 문자열 이밖에 실수형, bool, 집합, 객체 등 다양한 자료형들을 넣을 수 있다.

2. 딕셔너리 쌍 추가, 삭제하기, 값 가져오기

딕셔너리는 없는 key에 값을 넣어주면 key-value를 추가할 수 있다.

a = {1 : 'a'}
a[2] = 'b'
print(a) # {1: 'a', 2: 'b'}

a에는 2에 해당하는 key-value 쌍이 없었는데, 위와 같이 추가할 수 있다.

삭제는 list와 같이 del을 사용한다.

a = {1 : 'a'}
a[2] = 'b'
del a[1]
print(a) # {2: 'b'}

값을 가져오는 방법도 굉장히 간단하다. key 통해 value를 가져오면 된다.

grade = {'math' : 90}
print(grade['math']) # 90
print(grade['english']) # KeyError: 'english'

단, 없는 key값을 호출하면 error가 발생한다.

한가지 재밌는 것은 key로 올 수 있는 것들은 immutable한 것들이다. 즉, 불변하는 것들인데 우리가 아는 것은 숫자, 튜플, 문자열, bool 등이 있다.

그래서 튜플과 실수도 넣을 수도 있다.

grade = {(1,2) : 3, 2.1412 : 'number'}
grade[(1,2)] = 13
print(grade[(1,2)] , grade[2.1412]) # 13 number

단, 동일한 key로 값을 넣으면 값을 덮어쓰니 조심하도록 하자

grade = {'math': 2, 'math' : 20}
print(grade['math']) # 20
grade['math'] = 30
print(grade['math']) # 30

3. 딕셔너리 관련 메서드

3.1 keys

key들의 이름을 알고싶다면 keys()를 사용하면 키들을 반환해준다.

grade = {'math': 2, 'english': 30, 5: 10}
print(grade.keys()) # dict_keys(['math', 'english', 5])

dict_keys라는 요상한 값이 나오는데, 이들은 리스트는 아니더라도 기본적인 반복문을 실행할 수 있다. 그래서 다음과 같은 문법이 가능하다.

grade = {'math': 2, 'english': 30, 5: 10}

for k in grade.keys():
    print(k)

#math
#english
#5

dict_keys 말고도, dict_values, dict_items 등과 같은 객체들이 더 있다. 이들은 리스트가 아니므로 리스트 고유의 append, insert, pop, remove, sort함수를 수행할 수 없다. 그러나 리스트처럼 iterable할 수 있으므로 for문으로 순회가 가능하다.

dict_keys, dict_values, dict_items 모두 리스트로 변환이 가능한데, 변환하려면 다음과 같이하면 된다.

grade = {'math': 2, 'english': 30, 5: 10}
print(list(grade)) # ['math', 'english', 5]

list로 묶어내면 된다.

3.2 value 리스트 만들기

이번에는 value()메서드를 사용하면 된다.

grade = {'math': 2, 'english': 30, 5: 10}

print(grade.values()) # dict_values([2, 30, 10])

위에서 key값들을 얻어낼 때와 같이 values()로 값을 얻어내면 dict_values 객체가 나온다. 이 역시 list로 씌우면 리스트로 변환된다.

3.3 key, value 모두 얻기

items() 메서드를 사용하면 key, value 쌍으로 된 튜플을 dict_items 객체로 돌려준다. 마찬가지로 dict_itemslist로 감싸면 list에 담기게 된다.

grade = {'math': 2, 'english': 30, 5: 10}
print(grade.items()) # dict_items([('math', 2), ('english', 30), (5, 10)])
print(list(grade.items())) # [('math', 2), ('english', 30), (5, 10)]

3.4 key, value 쌍 모두 지우기

clear() 메서드를 사용하면 모든 key-value쌍을 지울 수 있다.

a = [1,2,3,4]
print(a.clear()) # None

3.5 get을 통해 key로 value얻기

get(key)라는 메서드는 key에 해당하는 value를 준다. 이는 일반적으로 key로 접근했을 때와 다를 바 없다. 차이는 해당하는 key가 없을 때이다. get(key)는 key가 없어도 에러를 반환하지 않고 None을 반환해서 더 안전하다.

a = {'name': 'pey', 'phone': '0123451'}
print(a.get('name'), a['name']) # pey pey
print(a.get('some')) # None
print(a['some']) # KeyError: 'some'

또한, get(key)는 두 번째 인자로, 만약 해당하는 key가 없으면 value를 반환해달라고 할 수 있다.

a = {'name': 'pey', 'phone': '0123451'}
print(a.get('name'), a['name']) # pey pey
print(a.get('some', 123)) # 123
print(a['some']) # KeyError: 'some'

에러로 부터 안전한 메서드이기 때문에 장점이 많다.

3.6 해당 key가 딕셔너리 안에 있는 지 조사하기 (in)

in키워드는 if문이나 평문에서 'a' in 'b' 로 'a'가 'b'에 있는 지 확인할 수 있는 키워드이다. 있다면 True, 없으면False```이다.

a = {'name': 'pey', 'phone': '0123451'}
print( 'name' in a) # True
print( 'some' in a) # False

다음과 같이 된다. 이를 통해 해당 딕셔너리에 어떤 키값이 있는 지 없는 지 확인할 수 있는 것이다.

참고로 in은 for문과 같은 반복문에서 사용되면 순회하는 데 사용할 수 있다. 딕셔너리의 경우 key값을 리턴해준다.

import copy

food = {'banana': 300, 'apple' : 200, 'pineapple' : 3000}
for k in food:
    print(k) # banana apple pineapple

단 위에도 말했듯이 딕셔너리는 순서를 보장하지 않아서 매번 순회마다 다르다. 상위 버전의 파이썬을 쓰면 고정된 순서로 나오는데 하위버전을 그렇지 않은 것을 확인할 수 있을 것이다. 때문에 순서를 보장하지 못한다는 것을 알 수 있다.

3.7 update를 동한 여러 값을 수정

단일 수정은 키로 접근하여 값을 바꾸면 되고, 여러 값의 수정은 update메서드를 사용한다. 키가 없는 값이면 추가된다.

import copy

food = {'banana': 300, 'apple' : 200, 'pineapple' : 3000}
food.update({'banana': 1200 , 'apple' : 10, 'price' : 90})
print(food) # {'banana': 1200, 'apple': 10, 'pineapple': 3000, 'price': 90}

4. 딕셔너리 변환

리스트나 튜플안에 key, value 형식으로 보기 좋게되어있다면 이를 dict()로 감싸 딕셔너리로 만들 수 있다.

foods = [['apple', 3] , ['banana', 5]]
print(dict(foods)) # {'apple': 3, 'banana': 5}
foods = [('apple', 3) , ('banana', 5)]
print(dict(foods)) # {'apple': 3, 'banana': 5}
foods = (('apple', 3) , ('banana', 5))
print(dict(foods)) # {'apple': 3, 'banana': 5}
foods = (['apple', 3] , ['banana', 5])
print(dict(foods)) # {'apple': 3, 'banana': 5}

다음과 같이 리스트와 튜플 안에 키-값 쌍이 예쁘게 있다면 dict로 변환이 가능하다.

5. 딕셔너리 복사

리스트와 마찬가지로 딕셔너리도 자신을 대입하면 참조값이 넘어가기 때문에, 원본이 얼마든지 수정 가능하다. 따라서 이를 조심하도록 하자

food = {'banana': 300, 'apple' : 200}
some = food
some['banana'] = 50123
print(food) # {'banana': 50123, 'apple': 200}

some을 바꾸었는데 food가 바뀐 것을 확인할 수 있다. 이를 해결하기 위해서는 copy의 deepcopy를 사용하면 된다. deepcopy는 새로운 객체를 만들어 값을 똑같이 만들어줄 뿐, 참조값이 넘어가는 것은 아니기 때문이다.

import copy

food = {'banana': 300, 'apple' : 200}
some = copy.deepcopy(food)
some['banana'] = 50123
print(food) # {'banana': 300, 'apple': 200}
print(some) # {'banana': 50123, 'apple': 200}

some의 값을 바꾸어도 food에 영향이 안가는 것을 확인할 수 있다.

6. pprint

pprint를 사용하면 dictionary를 쉽게 표현해준다.

from pprint import pprint as pp
a = {'name' : 'gyu', 'age': 20, 'house' :'seoul'}

print(a) # {'name': 'gyu', 'age': 20, 'house': 'seoul'}

pp(a) # {'age': 20, 'house': 'seoul', 'name': 'gyu'}

0개의 댓글