티스토리 뷰
728x90
해당 내용과 코드는 모두 '코딩의 기술' 책을 참고한 것입니다.
counters = {
'품퍼니켈': 2,
'사워도우': 1,
}
key = '밀'
if key in counters:
print(key)
count = counters[key]
else:
print(key) # 밀
count = 0
- 키가 없으면 디폴트 카운터인 값에 0을 딕셔너리에 넣고 카운터를 증가 시키는 방법으로 구현한다.
- if문과 키를 사용함으로서 딕셔너리에서 키를 두 번 읽고, 키에 대한 값을 한 번 대입하게 되는 경우이다
try:
count = counters[key]
except KeyError:
count = 0
counters[key] = count + 1
print(counters) # {'품퍼니켈': 2, '사워도우': 1, '밀': 1}
- 존재하지 않는 키에 접근할 때 발생시키는 KeyError 예외를 활용하는 방법
- 키를 한 번만 읽고, 값을 한 번만 대입하면 되므로 더 효울적임
- 딕셔너리에는 이런 식으로 키가 존재하면 그 값을 가져오고, 존재하지 않으면 디폴트 값을 반환하는 흐름이 자주 일어난다.
count = counters.get(key, 0)
counters[key] = count + 1
print(counters) # {'품퍼니켈': 2, '사워도우': 1, '밀': 1}
- 그러면 dict 내장 타입에는 이런 작업을 수행하는 get 의 메서드가 있음
- get의 두 번째 인자는 첫 번째 인자인 키가 딕셔너리에 들어 있지 않을 때 돌려줄 디폴트 값임
- 키를 한 번만 읽고 키를 한 번만 대입하는 방법
if key not in counters:
counters[key] = 0
counters[key] += 1
if key in counters:
counters[key] += 1
else:
counters[key] = 1
try:
counters[key] += 1
except KeyError:
counters[key] = 1
- in 식과 KeyError 를 사용하는 방식을 여러 방법으로 더 짧게 쓸 수도 있음
- 하지만 어느 방식을 써도 대입이 중복되므로 코드 가독성이 떨어짐
votes = {
'바게트' : ['철수', '순이'],
'치아바타': ['하니', '유리']
}
key = '브리오슈'
who = '단이'
if key in votes:
names = votes[key]
else:
votes[key] = names = []
print(votes) # {'바게트': ['철수', '순이'], '치아바타': ['하니', '유리'], '브리오슈': []}
names.append(who)
print(votes) # {'바게트': ['철수', '순이'], '치아바타': ['하니', '유리'], '브리오슈': ['단이']}
- in 을 사용하면 키가 있는 경우에는 키를 두 번 읽어야 하고, 키가 없는 경우에는 값을 한 번 대입하게 됨
- 이 예제는 키가 존재하지 않을 때 빈 리스트를 통해 디폴트 값으로 대입할 수 있음
- 이중 대입문인 votes[key] names = [] 는 키 대입을 두 줄이 아닌 한 줄로 처리
- 디폴트 값으로 빈 리스트를 딕셔너리에 넣고 나면 참조를 통해 내용 변경이 어려우므로 append를 호출한 다음 리스트를 다시 딕셔너리에 대입할 필요가 없다
try:
names = votes[key]
except KeyError:
votes[key] = names = []
names.append(who)
print(votes) # {'바게트': ['철수', '순이'], '치아바타': ['하니', '유리'], '브리오슈': ['단이']}
if (names := votes.get(key)) is None:
votes[key] = names = []
names.append(who)
print(votes) # {'바게트': ['철수', '순이'], '치아바타': ['하니', '유리'], '브리오슈': ['단이']}
- 좋은 코드
naems = votes.setdefault(key, [])
names.append(who)
print(votes) # {'바게트': ['철수', '순이'], '치아바타': ['하니', '유리'], '브리오슈': ['단이']}
- setdefault 메서드가 있다
- 이는 딕셔너리에서 키를 사용해 값을 가져오려고 시도함
- 해당 메서드는 키가 없으면 제공받은 디폴트 값을 키에 연관시켜 딕셔너리에 대입한 다음, 키에 연관된 값을 반환함
- 한 가지 함정은 키가 없으면 setdefault 에 전달된 디폴트 값이 별도로 복사되지 않고 딕셔너리에 직접 대입됨
data = {}
key = 'foo'
value = []
data.setdefault(key, value)
print('이전', data)
value.append('hello')
print('이후', data)
# 이전 {'foo': []}
# 이후 {'foo': ['hello']}
- 키에 해당하는 디폴트 값을 setdefault 에 전달할 때마다 그 값을 새로 만들어야 함
- 즉, 호출할 때마다 리스트를 만들어야 해서 성능이 크게 저하됨
count = counters.setdefault(key, 0)
counters[key] = count + 1
print(counters) # {'품퍼니켈': 2, '사워도우': 1, '밀': 5, 'foo': 1}
- 여기서는 굳이 setdefault 를 사용할 이유가 없다
- 카운터를 증가시키면 default 값이 굳이 필요 없기 때문이다
728x90
'Skills > Pythons' 카테고리의 다른 글
[Python] None 보다는 예외를 발생시키는 방법 (2) | 2022.12.13 |
---|---|
[Python] 딕셔너리 - defaultdict의 사용 (0) | 2022.12.08 |
[Python] Byres, Str의 차이 (2) | 2022.11.25 |
[Python] PEP8 스타일 코딩 (2) | 2022.11.25 |
[Python] 파이썬 버전 확인 (0) | 2022.11.25 |
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- Unsupervised learning
- 파이썬 클래스 계층 구조
- few-shot learning
- CNN
- 파이썬 딕셔너리
- 도커 컨테이너
- python
- stylegan
- 도커
- 파이썬 클래스 다형성
- 구글드라이브연동
- docker
- cs231n
- 구글드라이브서버연동
- vscode 자동 저장
- 파이썬
- clip
- 서버구글드라이브연동
- NLP
- style transfer
- support set
- Prompt
- prompt learning
- 서버에다운
- 퓨샷러닝
- 데이터셋다운로드
- 프롬프트
- 딥러닝
- 구글드라이브다운
- 구글드라이브서버다운
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
글 보관함
250x250