[PY4E] 파이썬 딕셔너리; dict() get() items()
1. 컬렉션 Collection
- 리스트나 딕셔너리 같은 변수를 가지는 상황
- 하나의 정보보다는 여러 개의 정보를 저장할 때 사용
2. 리스트 List
- 순서를 유지하는 값들의 선형 컬렉션의 일종
- 원소 추가 > 항상 끝에 붙음
- 값마다 위치 존재
3. 딕셔너리 Dictionary
- 파이썬의 가장 강력한 데이터 컬렉션
- 순서X, 고유의 라벨(키, key)을 갖고 있는 값을 넣는 '가방'
>> "조회 태그"를 달아 인덱스 매김
But, 기본적으로는 추가하는 순서대로 저장됨
- value 값은 변경 가능 BUT, key 값은 변경 불가
- Associative Arrays (연관 배열) 이라고도 함 = 키와 값으로 구성된 쌍
ㄴ키와 값 사이의 연결 관계
- 연관 배열의 다양한 이름
> property maps : Perl / PHP
> hash maps : Java
> property bags : C# / .Net
4. 딕셔너리 생성 dict()
- dict() or { }로 생성
- 값을 찾기 위해 숫자 대신, key 사용하는 것만 제외 시, list와 동일
- {}(중괄호)로 표현 / 키 : 값 쌍 목록을 가짐
- keys() : Key 리스트 만들기
- values() : Value 리스트 만들기
>>> ddd = dict()
>>> ddd['age'] = 21
>>> ddd['course'] = 182 #KEY = 문자 / Value = 숫자
>>> print(ddd)
{'age': 21, 'course': 182}
>>> ddd['age'] = 23 #값 수정 가능 >> key는 수정 불가
>>> print(ddd)
{'age': 23, 'course': 182}
>>> a = { } #비어있는 중괄호로도 빈 딕셔너리 생성가능
>>> print(a)
{}
5. 딕셔너리 활용
- 카운팅 : 대상이 얼마나 자주 보이는가
>>> ccc = dict()
>>> ccc['csev'] = 1 #딕셔너리에 내용 추가
>>> ccc['cwen'] = 1
>>> print(ccc)
{'csev': 1, 'cwen': 1}
>>> ccc['cwen'] = ccc['cwen'] + 1 #key 사용해서 값 변경
>>> print(ccc)
{'csev': 1, 'cwen': 2}
- update
: key가 string 문자열이면 key=value로 여러개 한번에 수정 및 추가 가능.
: 문자열x이면 {}로 한번에 변경 가능
- clear() : 'key:value' 쌍 모두 지우기
- pop(key) : 키를 통해 값을 반환 후 삭제
- popitem() : 키-값의 쌍을 튜플로 반환 후 삭제
dic= {'a':1, 'b':2, 'c':3}
# 변수 스타일로 여러개 한번에 추가 및 수정
dic.update({'a':4,'d':5})
print(dic) # {'a': 4, 'b': 2, 'c': 3, 'd': 5}
dic.update(a=100, f=[50,200], d=['ring', 'plus'])
print(dic) # {'a': 100, 'b': 2, 'c': 3, 'd': ['ring', 'plus'], 'f': [50, 200]}
dic.update({1:4, 2:5})
print(dic) # {'a': 100, 'b': 2, 'c': 3, 'd': ['ring', 'plus'], 'f': [50, 200], 1: 4, 2: 5}
k = ['a', 'b', 'c', 'd']
dic1, dic2 = {}, {}
dic1 = dic1.fromkeys(k) #키만 저장됨
dic2 = dic2.fromkeys(k, 1)
print(dic1) #{'a': None, 'b': None, 'c': None, 'd': None}
print(dic2) #{'a': 1, 'b': 1, 'c': 1, 'd': 1}
dic= {'a':1, 'b':2, 'c':3}
print(dic.pop('b')) #2
print(dic.popitem()) #('c', 3)
- Traceback 에러 > in 연산자 사용
: 딕셔너리에 없는 키를 참조하는 것은 오류 > in 연산자로 확인 후, 원소 추가
# in 활용
counts = dict()
names = ['csev', 'cwen', 'csev', 'zqian', 'cwen']
for name in names :
if name in counts:
counts[name] = counts[name] + 1
else :
counts[name] = 1
print(counts)
# not in 활용
counts = dict()
names = ['csev', 'cwen', 'csev', 'zqian', 'cwen']
for name in names :
if name not in counts:
counts[name] = 1
else :
counts[name] = counts[name] + 1
print(counts)
- get 메소드('key', default value)
: 키가 있는 지 확인 > 없다면 기본값 설정(Traceback 에러 없음)
: 위의 if와 in으로 풀어서 확인하는 과정이 간소화됨
>>> counts = dict()
>>> names = ['csev', 'cwen', 'csev', 'zqian', 'cwen']
>>> for name in names :
>>> counts[name] = counts.get(name, 0) + 1 #get의 두번째 숫자(0)가 "기본값"
>>> print(counts)
결과값 = {'csev': 2, 'cwen': 2, 'zqian': 1}
- 파일 불러와 / 유한 루프를 활용해 / 반복되는 문자 카운팅 / 최종적으로 가장 많이 사용한 단어 찾기
fname = input('Enter file: ')
if len(fname) < 1 : fname = 'clown.txt'
hand = open(fname)
di = dict()
for lin in hand:
lin = lin.rstrip()
#print(lin)
wds = lin.split()
#print(wds)
for w in wds: #모든 작업이 제대로 이루어지고 있는지 확인
if w in di:
print(w) #계산 값 출력
di[w] += 1
print('**Existing**')
else:
di[w] = 1
print('**NEW**')
print(w, di[w]) #판별 후 카운트 값 출력
print(di)
> 중간 중간에 print로 재대로 작동하는 지 CHECK
fname = input('Enter file: ')
if len(fname) < 1 : fname = 'clown.txt'
hand = open(fname)
di = dict()
for lin in hand:
lin = lin.rstrip()
wds = lin.split()
for w in wds:
#idiom: retiexe/create/update counter
di[w] = di.get(w,0) + 1
#print(w, 'new', di[w])
print(di)
> get() 메소드로 한 줄로 축약
> items() : *두 개*의 반복 변수를 사용하여 키-값 쌍을 연속 반환
...
#now we want to find the most common word
largest = -1 # v의 기본값이 0이었기 때문에 -1로 설정
theword = None
for k,v in di.items() : #키와 값 쌍을 반환하는 메소드(두개필요)
#print(k, v)
if v > largest :
largest = v
theword = k #cature/remember the word that was largest
print('Done', theword , largest)
> 가장 많이 나온 단어와 그 횟수를 최종 반환