튜플을 이용한 딕셔너리 정렬

매일 공부(ML)·2022년 2월 21일
0

Intro

튜플이라는 새로운 컬렉션과 튜플을 활용해 딕셔너리를 처리하는 방법에 대해 간단히 알아보았습니다.

튜플의 특성을 활용해 딕셔너리를 정렬할 수 있다


튜플 특성을 활용해 딕셔너리 정렬하기

지난 시간에 다음과 같은 튜플의 특성을 배웠습니다. 튜플끼리 비교가 가능하며, 이때 가장 왼쪽에 있는 값끼리 비교한다는 것이었습니다.

(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')]

가장 많이 등장한 단어 Top 10 출력하기

빈도수를 출력하는 프로그램을 다시 살펴보겠습니다.

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)

마지막으로 리스트 컴프리헨션(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')]
profile
성장을 도울 아카이빙 블로그

0개의 댓글