튜플이라는 새로운 컬렉션과 튜플을 활용해 딕셔너리를 처리하는 방법에 대해 간단히 알아보았습니다.
튜플의 특성을 활용해 딕셔너리를 정렬할 수 있다
지난 시간에 다음과 같은 튜플의 특성을 배웠습니다. 튜플끼리 비교가 가능하며, 이때 가장 왼쪽에 있는 값끼리 비교한다는 것이었습니다.
(0, 1, 2) < (5, 1, 2)
# True
(0, 1, 2000000) < (0, 3, 4)
# True
( 'Jones', 'Sally' ) < ('Jones', 'Sam')
# True
( 'Jones', 'Sally') > ('Adams', 'Sam')
# True
그리고 딕셔너리의 items 메소드를 실행하면 키와 값이 쌍을 이루는 튜플로 이루어진 리스트 형태로 반환된다는 것도 배웠습니다.
tups = d.items()
print(tups)
# dict_items([('csev', 2), ('cwen', 4)])
위의 두 가지 특성을 활용하면 키를 기준으로 딕셔너리를 정렬할 수 있습니다. 방법은 다음과 같습니다.
딕셔너리에서 items 메소드를 실행해 튜플로 이루어진 리스트 형태로 만든다.
이 리스트를 sorted 함수로 정렬한다. 그러면 각각의 튜플의 왼쪽 값, 즉 키를 기준으로 정렬이 된다.
즉, 다음과 같은 코드로 딕셔너리를 키를 기준으로 정렬할 수 있습니다.
d = {'b':1, 'a':10, 'c':22}
d.items()
# dict_items([('b', 1), ('a', 10), ('c', 22)])
sorted(d.items())
# [('a', 10), ('b', 1), ('c', 22)]
여기에서 정렬된 키와 값을 한 줄씩 보기 좋게 출력하려면 이렇게 코드를 작성하면 됩니다. 여기에서 k, v는 소괄호가 없지만 컴마로 나열되어있기 때문에 튜플입니다.
for k, v in sorted(d.items()):
print(k, v)
# a 10
# b 1
# c 22
여기에서 값을 기준으로 정렬하려면 조금의 아이디어만 있으면 됩니다. 방법은 다음과 같습니다.
딕셔너리에서 items 메소드를 실행한다.
튜플을 활용해 키와 값을 분리한다.
키와 값의 위치를 바꾼 리스트를 생성한다.
생성된 리스트를 정렬한다.
이 과정을 코드로 표현하면 다음과 같습니다. 실행결과를 보시면 값을 기준으로 오름차순 정렬이 된 것을 볼 수 있습니다.
c = {'a':10, 'b':1, 'c':22}
tmp = list()
for k, v in c.items() :
tmp.append( (v, k) )
print(tmp)
# [(10, 'a'), (1, 'b'), (22, 'c')]
tmp = sorted(tmp)
print(tmp)
# [(1, 'b'), (10, 'a'), (22, 'c')]
여기에서 만약 내림차순으로 정렬하고 싶다면 다음과 같이 sorted 함수에 reverse 옵션을 True로 설정하면 됩니다.
c = {'a':10, 'b':1, 'c':22}
tmp = list()
for k, v in c.items() :
tmp.append( (v, k) )
print(tmp)
# [(10, 'a'), (1, 'b'), (22, 'c')]
tmp = sorted(tmp, reverse=True)
print(tmp)
# [(22, 'c'), (10, 'a'), (1, 'b')]
빈도수를 출력하는 프로그램을 다시 살펴보겠습니다.
fhand = open('romeo.txt')
counts = {}
for line in fhand:
words = line.split()
for word in words:
counts[word] = counts.get(word, 0 ) + 1
이 코드가 실행되면 romeo.txt에 저장된 문장을 단어로 나눈 후, 각 단어와 그 빈도로 이루어진 딕셔너리가 생성되었던 것을 기억하실 것입니다.
이제 이 딕셔너리에 조금 전에 배웠던 키를 기준으로 내림차순 정렬하는 방법을 적용해보겠습니다.
lst = []
for key, val in counts.items():
newtup = (val, key)
lst.append(newtup)
lst = sorted(lst, reverse=True)
변수 이름이 조금 바뀌었을 뿐 조금 전에 봤던 코드와 동일한 형태입니다.
이 코드가 실행되면 [(빈도수, 단어이름), (빈도수, 단어이름), ..., (빈도수, 단어이름)] 과 같은 형태로 데이터가 정렬됩니다.
이제 여기에서 빈도수 상위 10개의 단어를 단어, 빈도수 순으로 출력해보겠습니다.
지금까지 배운 내용을 활용해 이렇게 간단히 코드로 표현할 수 있습니다.
for val, key in lst[:10] :
print(key, val)
조금 전에 작성한 코드의 전체 코드입니다.
fhand = open('romeo.txt')
counts = {}
for line in fhand:
words = line.split()
for word in words:
counts[word] = counts.get(word, 0 ) + 1
lst = []
for key, val in counts.items():
newtup = (val, key)
lst.append(newtup)
lst = sorted(lst, reverse=True)
for val, key in lst[:10] :
print(key, val)
마지막으로 리스트 컴프리헨션(List comprehension)이라는 것을 살펴보겠습니다.
이것은 조금 전에 작성했던 딕셔너리를 키를 기준으로 정렬해서 출력하는 코드입니다.
c = {'a':10, 'b':1, 'c':22}
tmp = list()
for k, v in c.items() :
tmp.append( (v, k) )
tmp = sorted(tmp)
print(tmp)
# [(1, 'b'), (10, 'a'), (22, 'c')]
그리고 다음의 코드는 정확히 위의 코드와 동일한 역할을 합니다.
c = {'a':10, 'b':1, 'c':22}
print( sorted( [ (v,k) for k,v in c.items() ] ) )
# [(1, 'b'), (10, 'a'), (22, 'c')]