본문 바로가기
코딩 연습/코딩배우기

[python] 딕셔너리(dict) 알아보기 - 생성, 루핑, 컴프리헨션, setfault, orderedDict

by good4me 2020. 8. 29.

goodthings4me.tistory.com

 

dict 생성

d1 = {'a': 1, 'b': 2, 'c': 3}
d2 = dict([('a', 1), ('b', 2), ('c', 3)])
d3 = dict(a = 1, b = 2, c = 3)
d4 = dict(zip(['a', 'b', 'c'], [1, 2, 3]))  # zip() 함수
d5 = dict({'a': 1, 'b': 2, 'c': 3})
#d6 = dict(('a', 1), ('b', 2), ('c', 3))  # TypeError
print(d1 == d2 == d3 == d4)  # True
print(d1)
print(d2)
print(d3)
print(d4)
print(d5)  # {'a': 1, 'b': 2, 'c': 3}  / d1~5 모두 동일

 

dict의 for loop

dic = dict(a = 1, b = 2, c = 3)

for d in dic:
    print(d, end=', ')  # a, b, c, / d에는 키(key)가 담김

for d in dic.keys():
    print(d, end=', ')  # a, b, c, / key가 순서대로 출력

for d in dic.values():
    print(d, end=', ')  # 1, 2, 3, / 값(value)이 순서대로 출력

for d in dic:
    print(dic[d], end=', ')  # 1, 2, 3, / dic[key]는 값(value)이 출력됨

for d in dic.items():  # ('a', 1), ('b', 2), ('c', 3) / (키, 값)이 순서대로 출력
    print(d, end=', ')

for dk, dv in dic.items():
    print(dk, dv, sep=':')  # 키와 값이 a, 1 형태로 출력 - 튜플 언패킹


print(dic.keys())  # dict_keys(['a', 'b', 'c'])
print(dic.values())  # dict_values([1, 2, 3])
print(dic.items())  # dict_items([('a', 1), ('b', 2), ('c', 3)])

good4me.co.kr

 

 dict의 대입과 수정

ds = dict(a = 10, b = 20, c = 30)
dc = ds
print(ds == dc)  # True
print(ds is dc)  # True

dc['a'] += 3
print(ds)  # {'a': 13, 'b': 20, 'c': 30}
print(dc)  # {'a': 13, 'b': 20, 'c': 30}


d = dict(a = 100, b = 200, c = 300)
di = d.items()
print(d == di)  # False
print(d is di)  # False
print(type(d))  # <class 'dict'>
print(type(di)) # <class 'dict_items'>
# di.keys()는 <class 'dict_keys'>, di.values()는 <class 'dict_values'> 객체임

print(d)  # {'a': 1, 'b': 2, 'c': 3}
print(di)  # dict_items([('a', 1), ('b', 2), ('c', 3)])

#di['a'] += 3  # TypeError: 'dict_items' object is not subscriptable
#di[0][1] += 3  # 인덱싱 지원 안함(에러 반환) 그럼, 너란 놈은??

d['a'] += 1
print(d)  # {'a': 101, 'b': 200, 'c': 300}
print(di) # dict_items([('a', 101), ('b', 200), ('c', 300)])
print(d.values())  # dict_values([101, 200, 300])

딕셔너리 수정사항이 뷰 객체에 그대로 반영됨

.keys(), .values(), .items() 메서드가 반환하는 객체를 뷰(view)객체라고 하며, 현재 딕셔너리 상태를 그대로 반영한다. 그리고, 모두 iterable 객체이다.

 

 dict 컴프리헨션

# 리스트 컴프리헨션과 유사함

d1 = dict(a = 1, b = 2, c = 3, d = 4, f = 5)
d2 = {k : v * 2 for k, v in d1.items()}
print(d2)  # {'a': 2, 'b': 4, 'c': 6, 'd': 8, 'f': 10}

d3 = {k : v for k, v in d1.items() if v % 2}
print(d3)  # {'a': 1, 'c': 3, 'f': 5}

 

dict 삭제

dic_d = {'one': 1,'two': 2,'three': 3,'four': 4, 'five': 5}
del dic_d['one']  # 키 'one' 삭제
print(dic_d)  # {'two': 2, 'three': 3, 'four': 4, 'five': 5}

p = (dic_d.popitem())
print(p)  # ('five', 5)
print(dic_d)  # {'two': 2, 'three': 3, 'four': 4}

 

존재하지 않는 key에 접근 시 처리 방법

dg = dict(a = 10, b = 20, c = 30)
#print(dg['d'])  # KeyError: 'd'

print(dg.get('d'))  # None - 에러 안남

 

dict --> 리스트로 만들기

print(list(dg.keys()))  # ['a', 'b', 'c']
print(list(dg.values()))  # [1, 2, 3]
print(list(dg.items()))  # [('a', 1), ('b', 2), ('c', 3)]

 

 딕셔너리에 대입 연산 시 키(key)가 존재할 때(수정)와 존재하지 않을 때(추가), setdefault() 메서드 사용법

speech = 'In ten days the world will witness a hallmark of our demorcracy . \
    The peaceful transfer of power from one freely-elected President to the next . \
    I commoitted to President Elect Trump that my administration would ensure the \
    smoothest possible transition, just as President Bush did for me .'

speech_list = speech.split(' ')

wordc = {}
for w in speech_list:
    if w in wordc:
        wordc[w] += 1 # dict wordc에 단어가 있으면 value(값) 1 증가
    else:
        wordc[w] = 1 # dict wordc에 단어가 없으면 단어 추가 후 1 대입

wordc_sorted = sorted(wordc) # 원본과 다른 sort된 객체 생성

print('== 원본 ==\n', wordc, '\n')
print('== key로 sort(sorted 사용)한 결과 ==\n',wordc_sorted, '\n') # key sort



# setdefault() 사용 시 --------------------------------

wordset = {}

for w in speech_list:
    wordset[w] = wordset.setdefault(w, 0) + 1 
    # setdefault(k, default) : key 있으면 그 키값(k[v]) 반환, 
    # 없으면 (k: default) 저장(k[v]=default)하고 값(default) 반환

print('== 원본 : setdefault() 적용 ==\n',wordset, '\n')

# value(값)인 숫자를 기준으로 정렬 (key=lambda 함수)
print('== value를 기준으로 정렬 ==') 
print(sorted(wordset.items(), key=lambda word: word[1], reverse=True), '\n')

# key를 기준으로 정렬
print('== key를 기준으로 정렬 ==\n', sorted(wordset.items(), key=lambda word: word[0]))


[실행 결과]

 

OrderDict 사용

# 파이썬 3.7부터 dict(딕셔너리) 저장 순서 유지되고, 있으나 순서에 상관없이 내용이 같으면 True이다.

d1 = dict(a = 1, b = 2, c = 3)
d2 = dict(c = 3, b = 2, a = 1)
print(d1 == d2)  # True


# dict 대신 OrderedDict를 사용해야 하는 상황
# dict의 저장 순서가 중요한 경우와 저장 순서를 변경할 경우에 OrderedDict를 사용함
from collections import OrderedDict  # OrderDict 사용 모듈 필요 

od1 = OrderedDict(a = 1, b = 2, c = 3)
od2 = OrderedDict(c = 3, b = 2, a = 1)
print(od1 == od2)  # False

# dict와 같이 for loop 가능
for od in od1.items():
    print(od, end=' ')  # ('a', 1) ('b', 2) ('c', 3)

# 저장 순서 변경 시
od1.move_to_end('b')
print(od1)  # OrderedDict([('a', 1), ('c', 3), ('b', 2)])

od2.move_to_end('a', last=False)
print(od2)  # OrderedDict([('a', 1), ('c', 3), ('b', 2)])


 

[참고자료] 윤성우의 열혈 파이썬 중급편

 

 

댓글