2020년 10월 30일
[파이썬] 딕셔너리(dict)와 집합(set)
I. 딕셔너리 (dict)
- 딕셔너리는 키와 값으로 구성된 자료 구조
- 파이썬에서는 저장 도구로 딕셔너리를 자주 사용
- 검색 기준은 키(key)로 저장, 키 값은 내부적으로 해시로 변환
- 해시 변환 가능한 객체로는 숫자, 문자열 등 변경 불가 객체 사용
가. 일반 딕셔너리
- [예제] 딕셔너리 객체 생성 및 확인
dictA = {'a' : 1, 'b' : 2} print(type(dictA)) dictA['a'] = 10 print(dictA) for key in dictA.keys() : # 딕셔너리의 키만 조회할 때 keys 메소드 사용 print(key) for value in dictA.values() : # 딕셔너리의 값만 조회할 때 values 메소드 사용 print(value) for key, value in dictA.items() : # 딕셔너리의 키/값 쌍 조회 시 items 메소드 사용 print("key:", key, ", value:", value) print(dictA.get('c', "키 없음")) # 없는 키 검색 시 예외 처리 [결과] <class 'dict'> {'a': 10, 'b': 2} a b 10 2 key: a , value: 10 key: b , value: 2 키 없음
- [예제] 딕셔너리 업데이트
dictA = {'a' : 1, 'b' : 2} dictB = {'c' : 3} dictA.update(dictB) # dictA 딕셔너리 변수에 dictB 추가 print(dictA) dictAcopy = dictA.copy() # dictA 딕셔너리 사본 생성 dictAcopy['d'] = dictB # 딕셔너리 사본에 키(d)/값(dictB) 추가 print(dictAcopy) dictAcopy['d']['c'] = 300 # 딕셔너리 내 딕셔너리의 값 변경 print(dictAcopy) [결과] {'a': 1, 'b': 2, 'c': 3} {'a': 1, 'b': 2, 'c': 3, 'd': {'c': 3}} {'a': 1, 'b': 2, 'c': 3, 'd': {'c': 300}}
나. 순서 딕셔너리
- 파이썬 딕셔너리는 순서 유지 안하므로 순서 유지 필요 시 OrderedDict 클래스 사용
- [예제] 순서 딕셔너리 사용
import collections as cols dictA = {'a' : 1, 'b' : 2} orderedDictA = cols.OrderedDict(dictA) # 순서 딕셔너리 필요 시 이 클래스로 객체 생성 orderedDictA['c'] = 3 orderedDictA.update({'d' : 10}) print(orderedDictA) [결과] OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 10)])
- 순서 딕셔너리 사용 시 ‘OrderedDict’가 붙음
II. 집합 (set)
가. 집합 (set)
- 리터럴 표기법으로 중괄호 사용
- 변경 불가능한 집합 객체인 frozenset으로 변환
- [예제] 집합 사용하기
setA = {1, 2, 3, 4, 5} fsetA = frozenset(setA) print(setA, fsetA) setA.add(6) # 원소 추가 print("교집합:", setA.intersection(fsetA)) # 교집합 print("합집합:", setA.union(fsetA)) # 합집합 setB = {1, 2, 3, 2, 1} # 집합(set)은 유일한 원소값만 가지므로 중복 시 하나의 값으로 처리 print("중복 원소 제거:", setB) setB.discard(3) # 원소 삭제 setB.remove(2) # 원소 삭제 print("삭제 후:", setB) setA.difference_update(setB) # 차집합 수행 결과로 내부 원소 변경 print("차집합 결과로 원소 변경:", setA) setA.update({10}) # 원소 추가 print("원소 추가:", setA) [결과] {1, 2, 3, 4, 5} frozenset({1, 2, 3, 4, 5}) 교집합: {1, 2, 3, 4, 5} 합집합: {1, 2, 3, 4, 5, 6} 중복 원소 제거: {1, 2, 3} 삭제 후: {1} 차집합 결과로 원소 변경: {2, 3, 4, 5, 6} 원소 추가: {2, 3, 4, 5, 6, 10}
나. 다중집합 (multi-set)
- 같은 원소를 가질 수 있는 집합
- [예제] 다중집합 사용하기
import collections as cols msetA = [1, 1, 2, 2, 3, 3, 3] # 다중집합은 대괄호([, ]) 사용 countMsetA = cols.Counter(msetA) # 다중집합 원소 개수 카운트 print("다중집합 카운트:", countMsetA) print("2의 원소 개수:", countMsetA[2]) countMsetB = countMsetA + countMsetA print("다중집합 덧셈연산:", countMsetB) countMsetC = countMsetB - countMsetA print("다중집합 뺄셈연산:", countMsetC) [결과] 다중집합 카운트: Counter({3: 3, 1: 2, 2: 2}) 2의 원소 개수: 2 다중집합 덧셈연산: Counter({3: 6, 1: 4, 2: 4}) 다중집합 뺄셈연산: Counter({3: 3, 1: 2, 2: 2})
III. Heap 자료구조
- Heap은 자료 저장 후 필요 시 마다 꺼내서 사용 가능
- [예제] Heap 자료구조 사용하기
class Heap : def __init__(self) : self._dict = {} def empty(self) : return True if len(self._dict) == 0 else False def pop(self, key) : # 저장소에서 원소 추출 if self._dict.get(key, 0) : # get 메소드는 예외 발생하지 않음 return self._dict.pop(key) else : return 0 def push(self, key, value) : return self._dict.setdefault(key, value) # setdefault는 키가 없으면 키/값 저장 후 조회, 키가 있으면 조회 def getHeap(self) : return self._dict.copy() h = Heap() print("empty 확인:", h.empty()) h.push("국어", 90) # 원소 하나 추가 h.push("수학", 80) # 원소 하나 추가 print("Heap 원소 확인:", h.getHeap()) h.pop("국어") # 원소 하나 제거 print("Heap 원소 확인:", h.getHeap()) h.pop("수학") # 원소 하나 제거 print("Heap 원소 확인:", h.getHeap()) [결과] empty 확인: True Heap 원소 확인: {'국어': 90, '수학': 80} Heap 원소 확인: {'수학': 80} Heap 원소 확인: {}
[참고]
- 잇플, “한 권으로 개발자가 원하던 파이썬 심화 A to Z”, 2019.11