Post

sort(), dict.get()

sort()

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
class Tool:
    def __init__(self, name, weight):
        self.name = name
        self.weight = weight

    def __repr__(self):
        return f'Tool({self.name!r}, {self.weight})'

tools = [
    Tool('수준계', 3.5),
    Tool('해머', 1.25),
    Tool('스크류드라이버', 0.5),
    Tool('', 0.25),
]

print('미정렬:', repr(tools))
>>> 미정렬: [Tool('수준계', 3.5), Tool('해머', 1.25), Tool('스크류드라이버', 0.5), Tool('', 0.25)]

tools.sort(key=lambda x: x.name)
print('정렬: ', tools)
>>> 정렬:  [Tool('', 0.25), Tool('수준계', 3.5), Tool('스크류드라이버', 0.5), Tool('해머', 1.25)

tools.sort(key=lambda x: x.weight)
print('무거운순 정렬:', tools)
>>> 무거운순 정렬: [Tool('수준계', 3.5), Tool('해머', 1.25), Tool('스크류드라이버', 0.5), Tool('', 0.25)]

위의 예시처럼 key로 전달된 람다 함수에서는 원소에 접근하거나 인덱스를 이용해 이용하거나 하는 등 제대로 작동하는 모든 식을 사용할 수 있다.

문자열 타입과 같은 경우, 람다식을 활용해 값을 변형할 수도 있다

1
2
3
4
5
6
7
8
9
places = ['home', 'work', 'New York', 'Paris']
places.sort()

print('대소문자 구분:', places)
>>> 대소문자 구분: ['New York', 'Paris', 'home', 'work']

places.sort(key=lambda x: x.lower())
print('대소문자 무시:', places)
>>> 대소문자 무시: ['home', 'New York', 'Paris', 'work']

dict.get()

딕셔너리와 상호작용하는 기본 3개의 연산은 키나 키와 연관된 값에 접근하고 대입하고 삭제하는 것이다. 그런데 어떤 키에 접근하거나 키를 삭제할 때 그 키가 딕셔너리에 없을 수도 있다.

예를들어 투표를 할 때 카운터를 증가시키려면, 먼저 키가 딕셔너리에 존재하는지 확인해야 한다.

키가 존재하지 않는 다면 ‘{키:0}’ 을 딕셔너리에 넣은다음 카운터를 1 증가시켜야 한다.

이렇게 하려면 아래처럼, 딕셔너리에서 키를 두번 읽고 키에대한 값을 한번 대입해야 한다.

1
2
3
4
5
6
7
key = 'starbucks'
if key in counters:
	count = counters[key]
else:
	count = 0

counters[key] = count + 1

KeyError 를 활용하면 키를 한번만 읽고, 한번만 대입하면 되므로 좀 더 효율적이다.

1
2
3
4
5
6
try:
	count = counters[key]
except:
	count = 0

counters[key] = count + 1

딕셔너리에서는 이렇게 키가 존재하면 그 값을 가져오고, 없다면 디폴트 값을 반환하는 흐름이 꽤 자주 일어나고 이런 작업을 위한 get 메서드가 있다.

1
2
3
# get 메서드의 두번째 인자는 첫 번째 인자인 키가 없을 때 돌려줄 디폴트 값
count = counters.get(key,0)
counters[key] = count +1

만약 득표수만 체크하는 것이 아니라 어던 사람의 어떤 키에 투표했는지 알고싶다면

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
votes = {
    '바게트': ['철수', '순이'],
    '치아바타': ['하니', '유리'],
}
key = '브리오슈'
who = '단이'

if key in votes:
    names = votes[key]
else:
    votes[key] = names = []

names.append(who)
print(votes)

>>> {'바게트': ['철수', '순이'], '치아바타': ['하니', '유리'], '브리오슈': ['단이']}

votes[key] = names = [] 과 같이 이중 대입문으로 처리하면, 참조를 통해 리스트 내용을 변경할 수 있으므로 append를 호출한 다음 리스트를 다시 딕셔너리에 대입할 필요는 없다.

위의 경우도 get 메서드를 활용하면 더욱 간결해진다

1
2
3
4
5
names = votes.get(key, None)
if names is None:
    votes[key] = names = []

names.append(who)

대입식을 사용하면 더 짧고 가독성있게 작성할 수 있다.

1
2
3
4
if (names := votes.get(key)) is None:
    votes[key] = names = []

names.append(who)
This post is licensed under CC BY 4.0 by the author.