딕셔너리에 키-값 쌍을 추가하는 메서드 2가지
setdefault
: 키-값 쌍 추가update
: 키의 값 수정, 키가 없으면 키-값 쌍 추가setdefault
에 키만 지정하면 값에 None
을 저장>>> x = {'a': 10, 'b': 20, 'c': 30, 'd': 40}
>>> x.setdefault('e')
>>> x
{'a': 10, 'b': 20, 'c': 30, 'd': 40, 'e': None}
>>> x = {'a': 10, 'b': 20, 'c': 30, 'd': 40, 'e': None}
>>> x.setdefault('f', 100)
100
>>> x
{'a': 10, 'b': 20, 'c': 30, 'd': 40, 'e': None, 'f': 100}
update(딕셔너리)
처럼 딕셔너리를 넣어서 값 수정update(리스트)
, update(튜플)
은 리스트와 튜플로 값 수정update(반복가능한객체)
는 키-값 쌍으로 된 반복 가능한 객체로 값 수정🔎>>> x = {'a': 10, 'b': 20, 'c': 30, 'd': 40}
>>> x.update(a=90) # 작은따옴표, 큰따옴표 생략
>>> x
{'a': 90, 'b': 20, 'c': 30, 'd': 40}
# 키-값 쌍 추가
>>> x.update(e=50)
>>> x
{'a': 90, 'b': 20, 'c': 30, 'd': 40, 'e': 50}
# 값 한꺼번에 수정
>>> x.update(a=900, f=60)
>>> x
{'a': 900, 'b': 20, 'c': 30, 'd': 40, 'e': 50, 'f': 60}
# 딕셔너리를 사용해 숫자 넣기
>>> y = {1: 'one', 2: 'two'}
>>> y.update({1: 'ONE', 3: 'THREE'})
>>> y
{1: 'ONE', 2: 'two', 3: 'THREE'}
# update(리스트)
>>> y.update([[2, 'TWO'], [4, 'FOUR']])
>>> y
{1: 'ONE', 2: 'TWO', 3: 'THREE', 4: 'FOUR'}
# update(반복가능한객체)
>>> y.update(zip([1, 2], ['one', 'two']))
>>> y
{1: 'one', 2: 'two', 3: 'THREE', 4: 'FOUR'}
📎 참고) setdefault와 update의 차이
setdefault
: 키-값 쌍 추가만 할 수 있고, 이미 들어있는 키의 값은 수정 불가능update
: 키-값 쌍 추가와 값 수정 모두 가능>> x = {'a': 10, 'b': 20, 'c': 30, 'd': 40} >> x.setdefault('a', 90) 10 >> x # 값 수정 불가능 {'a': 10, 'b': 20, 'c': 30, 'd': 40}
>>> x = {'a': 10, 'b': 20, 'c': 30, 'd': 40}
>>> x.pop('a')
10
>>> x
{'b': 20, 'c': 30, 'd': 40}
>>> x.pop('z', 0) # 딕셔너리에 키가 없으므로 기본값으로 지정한 0 반환
0
>>> x = {'a': 10, 'b': 20, 'c': 30, 'd': 40}
>>> del x['a']
>>> x
{'b': 20, 'c': 30, 'd': 40}
#파이썬 3.6이상 : 마지막 키-값 쌍 삭제 뒤 반환
>>> x = {'a': 10, 'b': 20, 'c': 30, 'd': 40}
>>> x.popitem()
('d', 40)
>>> x
{'a': 10, 'b': 20, 'c': 30}
#파이썬 3.5 이하 : 임의의 키-값 쌍 삭제 뒤 반환, 매번 삭제하는 키-값 쌍이 달라짐
>>> x = {'a': 10, 'b': 20, 'c': 30, 'd': 40}
>>> x.clear()
>>> x
{}
>>> x = {'a': 10, 'b': 20, 'c': 30, 'd': 40}
>>> x.get('a')
10
>>> x.get('z', 0) # z라는 키가 없어 지정했던 기본값 0 출력
0
>>> x = {'a': 10, 'b': 20, 'c': 30, 'd': 40}
>>> x.items()
dict_items([('a', 10), ('b', 20), ('c', 30), ('d', 40)])
>>> x.keys()
dict_keys(['a', 'b', 'c', 'd'])
>>> x.values()
dict_values([10, 20, 30, 40])
위 메서드들은 보통 for 반복문과 조합해서 사용
>>> keys = ['a', 'b', 'c', 'd'] # 먼저 키가 들어있는 리스트 준비(튜플도 가능)
>>> x = dict.fromkeys(keys)
>>> x
{'a': None, 'b': None, 'c': None, 'd': None}
>>> keys = ['a', 'b', 'c', 'd']
>>> y = dict.fromkeys(keys, 100)
>>> y
{'a': 100, 'b': 100, 'c': 100, 'd': 100}
📎 참고) defaultdict 사용하기
위에서 사용한 딕셔너리(dict)는 없는 키에 접근했을 경우 에러가 발생>> x = {'a': 0, 'b': 0, 'c': 0, 'd': 0} >> x['z'] # 키 'z'는 없음 Traceback (most recent call last): File "<pyshell#5>", line 1, in <module> x['z'] KeyError: 'z'
이때는 defaultdict를 사용
- defaultdict(기본값생성함수)
- 없는 키에 접근하더라도 에러가 발생하지 않으며 기본값을 반환
- collections 모듈에 들어있으며 기본값 생성 함수를 넣는다.
>> from collections import defaultdict # collections 모듈에서 defaultdict를 가져옴 >> y = defaultdict(int) # int로 기본값 생성
기본값을 0으로 설정했기 때문에 키의 값을 가져와보면 0이 나온다.
>> y['z'] 0
int를 넣었는데 기본값이 0인 이유는
>> int() 0 # int에 아무것도 넣지 않고 호출하면 0 반환
0이 아닌 다른 값을 기본값으로 설정하고 싶다면 기본값 생성 함수를 만들어서 넣으면 된다.
>> z = defaultdict(lambda: 'python') >> z['a'] 'python' >> z[0] 'python'
for i in x:
처럼 for
반복문에 딕셔너리를 지정한 뒤에 print
로 변수 i
를 출력해보면 키만 출력된다.
>>> x = {'a': 10, 'b': 20, 'c': 30, 'd': 40}
>>> for i in x:
print(i, end=' ')
# 실행결과
a b c d
키와 값을 모두 출력하려면 for in
뒤에 딕셔너리를 지정하고 items
사용한다.
for 키, 값 in 딕셔너리.items():
반복할 코드
>>> x = {'a': 10, 'b': 20, 'c': 30, 'd': 40}
>>> for key, value in x.items():
print(key, value)
# 실행결과
a 10
b 20
c 30
d 40
for key, value in x.items():
는 딕셔너리 x에서 키-값 쌍을 꺼내서 키는 key
에 값은 value
에 저장하고, 꺼낼 때마다 코드를 반복한다.
in
다음에 딕셔너리를 직접 지정하고 items
를 사용해도 무방
for key, value in {'a': 10, 'b': 20, 'c': 30, 'd': 40}.items():
print(key, value)
>>> x = {'a': 10, 'b': 20, 'c': 30, 'd': 40}
>>> for key in x.keys():
print(key, end=' ')
# 실행결과
a b c d
>>> x = {'a': 10, 'b': 20, 'c': 30, 'd': 40}
>>> for value in x.values():
print(value, end=' ')
# 실행결과
10 20 30 40
딕셔너리도 for 반복문과 if 조건문을 사용하여 딕셔너리를 생성할 수 있다.
for in
다음에 딕셔너리를 지정하고 items
사용키: 값
형식으로 변수나 값을 배치하여 딕셔너리 생성>>> keys = ['a', 'b', 'c', 'd']
>>> x = {key: value for key, value in dict.fromkeys(keys).items()}
>>> x
{'a': None, 'b': None, 'c': None, 'd': None}
dict.fromkeys(keys).items()
로 키-값 쌍을 구한 뒤 키는 변수 key
, 값은 변수 value
에 꺼내고 최종적으로 key
와 value
를 이용하여 딕셔너리를 만든다.
x = {key: value for key, value in dict.fromkeys(keys).items()}
keys로 키만 가져온 뒤 특정 값을 넣거나, values로 값을 가져온 뒤 값을 키로 사용할 수도 있다.
>>> {key: 0 for key in dict.fromkeys(['a', 'b', 'c', 'd']).keys()} # 키만 가져옴
{'a': 0, 'b': 0, 'c': 0, 'd': 0}
>>> {value: 0 for value in {'a': 10, 'b': 20, 'c': 30, 'd': 40}.values()} # 값을 키로 사용
{10: 0, 20: 0, 30: 0, 40: 0}
키와 값의 자리를 바꾸는 등 여러 가지로 응용 가능
>>> {value: key for key, value in {'a': 10, 'b': 20, 'c': 30, 'd': 40}.items()} # 키-값 자리를 바꿈
{10: 'a', 20: 'b', 30: 'c', 40: 'd'}
for
반복문으로 반복하면서 del
로 삭제x = {'a': 10, 'b': 20, 'c': 30, 'd': 40}
for key, value in x.items():
if value == 20: # 값이 20이면
del x[key] # 키-값 쌍 삭제
print(x)
# 실행결과
Traceback (most recent call last):
File "C:\project\dict_del_by_value_error.py", line 3, in <module>
for key, value in x.items():
RuntimeError: dictionary changed size during iteration
딕셔너리의 크기가 바뀌었다는 에러 발생. 즉, 딕셔너리는 for 반복문으로 반복하면서 키-값 쌍을 삭제하면 안 된다.
if
조건문을 사용하여 삭제할 값 제외>>> x = {'a': 10, 'b': 20, 'c': 30, 'd': 40}
>>> x = {key: value for key, value in x.items() if value != 20}
>>> x
{'a': 10, 'c': 30, 'd': 40}
직접 키-값 쌍을 삭제하는 방식이 아니라 삭제할 키-값 쌍을 제외하고 남은 키-값 쌍으로 딕셔너리를 새로 만드는 방식
terrestrial_planet = {
'Mercury': {
'mean_radius': 2439.7,
'mass': 3.3022E+23,
'orbital_period': 87.969
},
'Venus': {
'mean_radius': 6051.8,
'mass': 4.8676E+24,
'orbital_period': 224.70069,
},
'Earth': {
'mean_radius': 6371.0,
'mass': 5.97219E+24,
'orbital_period': 365.25641,
},
'Mars': {
'mean_radius': 3389.5,
'mass': 6.4185E+23,
'orbital_period': 686.9600,
}
}
print(terrestrial_planet['Venus']['mean_radius']) # 6051.8
# 실행결과
6051.8
딕셔너리 terrestrial_planet
에 키 'Mercury'
, 'Venus'
, 'Earth'
, 'Mars'
가 들어있고, 이 키들은 다시 값 부분에 딕셔너리가 들어있다.
[]
)를 단계만큼 붙이고 키 지정print(terrestrial_planet['Venus']['mean_radius'])
# 딕셔너리가 두 단계로 구성되어 있으므로 대괄호 두 번 사용
# 6051.8
>>> x = {'a': 0, 'b': 0, 'c': 0, 'd': 0}
>>> y = x
y = x와 같이 딕셔너리를 다른 변수에 할당하면 딕셔너리는 두 개가 될 것 같지만 실제로는 딕셔너리가 한 개이다.
>>> x is y
True
즉, 변수 이름만 다를 뿐 딕셔너리 x와 y는 같은 객체이다.
>>> y['a'] = 99
>>> x
{'a': 99, 'b': 0, 'c': 0, 'd': 0}
>>> y
{'a': 99, 'b': 0, 'c': 0, 'd': 0}
값을 변경하면 딕셔너리 x와 y에 모두 반영된다.
완전히 두 개로 만들려면 copy
메서드로 모든 키-값 쌍을 복사
>>> x = {'a': 0, 'b': 0, 'c': 0, 'd': 0}
>>> y = x.copy()
>>> x is y # 서로 다른 객체
False
>>> x == y # 키-값 쌍은 같으므로
True
>>> y['a'] = 99
>>> x
{'a': 0, 'b': 0, 'c': 0, 'd': 0}
>>> y
{'a': 99, 'b': 0, 'c': 0, 'd': 0} # 서로 영향을 미치지 않는다
>>> x = {'a': {'python': '2.7'}, 'b': {'python': '3.6'}}
>>> y = x.copy()
# y값 변경 시 x, y 모두 반영
>>> y['a']['python'] = '2.7.15'
>>> x
{'a': {'python': '2.7.15'}, 'b': {'python': '3.6'}}
>>> y
{'a': {'python': '2.7.15'}, 'b': {'python': '3.6'}}
copy
모듈의 deepcopy
함수를 사용>>> x = {'a': {'python': '2.7'}, 'b': {'python': '3.6'}}
>>> import copy # copy 모듈을 가져옴
>>> y = copy.deepcopy(x) # copy.deepcopy 함수를 사용하여 깊은 복사
>>> y['a']['python'] = '2.7.15'
>>> x
{'a': {'python': '2.7'}, 'b': {'python': '3.6'}}
>>> y
{'a': {'python': '2.7.15'}, 'b': {'python': '3.6'}}
copy.deepcopy
함수는 중첩된 딕셔너리에 들어있는 모든 딕셔너리를 복사하는 깊은 복사(deep copy)를 해준다.다음 소스 코드를 완성하여 평균 점수가 출력되게 만드세요.
maria = {'korean': 94, 'english': 91, 'mathematics': 89, 'science': 83}
__________________________
print(average)
# 실행결과
89.25
# 정답
average = sum(maria.values()) / len(maria)
여기서 평균 점수를 구하려면 딕셔너리의 값을 모두 더한 뒤 딕셔너리의 키 개수로 나눠주어야 한다.
딕셔너리에서 값을 모두 더하려면 sum(maria.values())
와 같이 values
로 값을 모두 가져온 뒤 sum
함수 사용
키의 개수는 len(maria)
처럼 len
으로 구한다.
sum
으로 구한 값을 len(maria)
로 나눠주면 평균을 구한다.