#!/usr/bin/env python # coding: utf-8 # *** # *** # # 12. 사전(Dictionaries) # *** # *** # *** # ## 1 사전 활용법 # *** # - 사전(Dictionary) 객체의 특징 # - 집합적 자료형 # - 자료의 순서를 정하지 않는 매핑(Mapping)형 # - 키(Key)를 이용하여 값(Value)에 접근 # - 시퀀스 자료형은 아님 # - 키와 값의 매핑 1개를 아이템(item)이라고 부름 # In[1]: member = {'basketball': 5, 'soccer': 11, 'baseball': 9} print(member['baseball']) # 검색 # - 값을 저장할 시에 키를 사용 # - 키가 없다면 새로운 키와 값의 아이템이 생성 # - 키가 이미 존재한다면 그 키에 해당하는 값이 변경 # In[2]: member = {'basketball': 5, 'soccer': 11, 'baseball': 9} member['volleyball'] = 7 # 새로운 아이템 설정 member['volleyball'] = 6 # 변경 print(member) print(len(member)) # 아이템의 개수 반환 # - 사전을 출력하면 각 아이템들이 임의의 순서로 출력된다. # - 마치 순서대로 출력이 되는 것 처럼 보이지만, 사전내에 있는 아이템들은 순서정보가 없음. # # - 내부적으로 키 내용에 대해 해쉬(Hash) 기법을 사용 # - 검색 속도가 매우 빠름 # - [참고]: http://www.laurentluce.com/posts/python-dictionary-implementation/ # - 키와 값 매핑에 대한 아이템을 삭제할 때에는 del과 함께 키값 명시 # In[3]: member = {'basketball':5, 'soccer':11, 'baseball':9} del member['basketball'] # 항목 삭제 print(member) # - [중요] 키는 변경 불가능 (Immutable) 자료만 가능 # - 문자열, 숫자, 튜플은 가능 # - 리스트, 사전은 키가 될 수 없음 # - 반면에 사전에 입력되는 값은 임의의 객체 # In[3]: d = {} d['str'] = 'abc' d[1] = 4 d[(1,2,3)] = 'tuple' print(d) # In[4]: d[[1,2,3]] = 'list' # 리스트는 키가 될 수 없다. # In[5]: d[{1:2}] = 3 # 사전은 키가 될 수 없다. # - 함수 이름(함수 객체)은 사전의 키나 값으로 사용 가능함 # In[6]: def add(a, b): return a + b def sub(a, b): return a - b action = {0: add, 1: sub} # 함수 이름을 사전의 값으로 사용 print(action[0](4, 5)) print(action[1](4, 5)) # In[7]: action2 = {add: 1, sub: 2} # 함수 이름을 사전의 키로 사용 print(action2[add]) # - 사전을 생성하는 다른 방법: 내장함수 dict() 사용 # In[8]: d = dict() print(type(d)) print() print(dict(one=1, two=2)) print(dict([('one', 1), ('two', 2)])) print(dict({'one':1, 'two':2})) # - [중요] zip(A, B): 두 개의 컨테이너/시퀀스 자료 A, B에 속한 원소들을 순서대로 쌍으로 묶은 튜플들을 반환할 수 있는 zip 객체 반환 # - zip 객체를 사전으로 변환하기 # In[10]: keys = ['one', 'two', 'three'] values = (1, 2, 3) print(zip(keys, values)) print(dict(zip(keys, values))) # In[1]: keys = ['one', 'two', 'three', 'four'] values = (1, 2, 3) print(dict(zip(keys, values))) # In[2]: keys = ['one', 'two', 'three'] values = (1, 2, 3, 4) print(dict(zip(keys, values))) # - zip 객체를 리스트로 변환하기 # In[3]: keys = ['one', 'two', 'three'] values = (1, 2, 3) print(list(zip(keys, values))) # *** # ## 2 사전 메소드 # *** # - 사전이 지원하는 중요 메소드 # - D.keys(): 사전 D에서 키를 차례로 반환할 수 있는 dict_keys 객체 반환 # - D.values(): 사전 D에서 값을 차례로 반환할 수 있는 dict_values 객체 반환 # - D.items(): 사전 D에서 각 (키, 값) 아이템을 차례로 반환할 수 있는 dict_items 객체 반환 # - key in D: 사전 D안에 key를 키값을 가진 아이템이 있는지 확인 # In[12]: phone = {'jack': 9465215, 'jin': 1111, 'Joseph': 6584321} print(phone.keys()) print(phone.values()) print(phone.items()) print() print('jack' in phone) # 'jack'이 phone의 키에 포함되어 있는가? print('lee' in phone) # - D2 = D.copy(): 사전 D를 복사하여 D2 사전에 할당한다. # In[10]: phone = {'jack':9465215, 'jin':1111, 'Joseph':6584321} p = phone # 사전 레퍼런스 복사. 사전 객체는 공유된다. phone['jack'] = 1234 # phone을 변경하면 print(phone) print(p) # p도 함께 변경된다. print() ph = phone.copy() # 사전복사. 별도의 사전 객체가 마련된다. phone['jack'] = 1111 # phone을 바꿔도 print(phone) print(ph) # ph는 바뀌지 않는다. # - [주의] D.copy()는 Shallow Copy를 수행한다. # In[4]: phone = {'a': [1,2,3], 'b': 4} phone2 = phone.copy() print(phone) print(phone2) print() phone['b'] = 100 print(phone) print(phone2) print() phone['a'][0] = 100 print(phone) print(phone2) # ![image](../images/shallow_copy.png) # In[13]: ph = {'jack': 9465215, 'jin': 1111, 'Joseph': 6584321} print(ph.get('jack')) # 'jack'에 대한 값을 얻는다. ph['jack']과 같다. print(ph.get('gslee')) # 'gslee'에 대한 값을 얻는다. 값이 없는 경우 None반환 # In[15]: ph = {'jack': 9465215, 'jin': 1111, 'Joseph': 6584321} print(ph['gslee']) # ph['gslee']는 키가 없는 경우 예외발생 # In[16]: ph = {'jack': 9465215, 'jin': 1111, 'Joseph': 6584321} print(ph.get('gslee', 5284)) # 인수를 하나 더 제공하면 'gslee'가 없는 경우에 5284 리턴 print(ph) # 사전에는 변화가 없다 print() print(ph.popitem()) # 임의의 아이템을 꺼낸다. print(ph) print() print(ph.popitem()) # 임의의 아이템을 꺼낸다. print(ph) print() print(ph.pop('jack')) # 키 값을 통해 해당 아이템을 지정하여 꺼낸다. print(ph) # In[17]: phone = {'jack': 9465215, 'jin': 1111, 'Joseph': 6584321} ph = {'kim': 12312, 'lee': 9090} phone.update(ph) # 사전 phone의 내용을 ph으로 추가 갱신 print(phone) print() phone.clear() # 사전의 모든 입력을 없앤다. print(phone) # *** # ## 3 루프를 이용한 사전 내용 참조 # *** # - 사전의 모든 키값을 순차적으로 참조하는 방법 # In[16]: D = {'a':1, 'b':2, 'c':3} for key in D.keys(): print(key, D[key]) # - 사전 자체를 for루프에 활용하면 키에 대한 루프가 실행된다. # In[17]: D = {'a':1, 'b':2, 'c':3} for key in D: print(key, D[key]) # - 키와 값을 동시에 참조하려면 D.items()를 활용한다. # In[18]: for key, value in D.items(): print(key, value) # - 사전에 입력된 아이템들은 일정한 순서가 없다. # - 키값에 대한 정렬은 아이템들을 리스트로 뽑은 다음에 해당 리스트에 있는 sort() 함수를 활용한다. # In[22]: D = {'c':1, 'a':2, 'b':3} #items = D.items() items = list(D.items()) print(items) print() items.sort() print(items) print() for k, v in items: print(k, v) # - 위 리스트에서 각 튜플 원소의 두번째 값을 기준으로 정렬을 해보시오 (각자 실습) #

참고 문헌: 파이썬(열혈강의)(개정판 VER.2), 이강성, FreeLec, 2005년 8월 29일