본문 바로가기
python/메모장

[Python] 리스트, 딕셔너리 순위 매기기

by GJ999 2023. 1. 8.

데이터를 다루다 보면, 데이터의 순위를 매겨서 최고값, 최저값, 중간값 등 순위에 따른 값을 볼 경우가 많다.

이를 리스트와 딕셔너리의 경우에 대해 알아보고자 한다.

순위를 알기 위해서는 정렬이 필수다.

리스트는 sort를 통해 정렬을 하며, 기본값은 오름차순, reverse = True를 하면 내림차순이 된다.

1. 리스트 정렬 내림차순, 오름차순 < list.sort( reverse = True) >

  • 오름차순 정렬 (기본값)
>>> l1 = [1135, 555, 7878, 123]
>>> l1.sort()
>>> print(l1)
[123, 555, 1135, 7878]
  • 내림차순 정렬
>>> l1 = [1135, 555, 7878, 123]
>>> l1.sort(reverse = True)
>>> print(l1)
[7878, 1135, 555, 123]

2. 리스트 정렬 key < list.sort( key = 함수)  >

리스트 안에 문자열들이 존재한다고 했을 때, 문자열 길이에 따라 정렬을 해보자.

>>> l2 = ['홍길동', '차차', '대한민국', '가나다라마바사']
>>> l2.sort(key = len, reverse = True)
>>> print(l2)
['가나다라마바사', '대한민국', '홍길동', '차차']

sort 함수의 인수 중 key를 활용하여 내림차순으로 정렬을 했다.

key에 들어가야하는건 함수만이 가능하며, 여기서는 글자의 길이를 측정하는 len 함수를 통해 정렬을 사용했다.

3. 딕셔너리 순위매기기

예를 들어, 어떤 가게에서 메뉴판이 있다고 가정하고, 그 중 제일 비싼 메뉴을 알고 싶다고 해보자.

예제 데이터는 다음과 같다.

>>> menu = {
...     '김치찌개' : 12000,
...     '감자탕' : 20000,
...     '된장찌개' : 11000,
...     '해장국' : 10000,
...     '순대모듬' : 13000,
... }

※ 참고로 딕셔너리 인풋 데이터 값을 넣을 때 마지막에 쉼표(,)로 끝나도 안넣은 것과 동일하며, 이렇게 하면 코드를 수정할 때 복사, 붙여넣기가 비교적 쉽다는 장점이 있다.

  • key값 리스트 변환 후 values 값에 따라 정렬
>>> names = list(menu.keys())
>>> names.sort(key = menu.get, reverse = True)
>>> print(names)
['감자탕', '순대모듬', '김치찌개', '된장찌개', '해장국']

여기서는 딕셔너리의 key값인 메뉴명들을 리스트화 시키고, 이를 value값인 음식값에 따라 메뉴명들을 내림차순한 것이다. 이때 value값들을 기준으로 삼기 위해, 딕셔너리의 내장함수인 get 함수를 사용했다.

※ 참고로 딕셔너리의 get함수는 key값을 입력하면 해당 key값에 대응되는 value값을 반환하는 함수다.

>>> menu.get('김치찌개')
12000
  • 신규 딕셔너리 생성후, 정렬한 리스트에 따른 순위매기기
>>> ranks = {}
>>> for i, name in enumerate(names,1):
...     ranks[name] = i
>>> ranks
{'감자탕': 1, '순대모듬': 2, '김치찌개': 3, '된장찌개': 4, '해장국': 5}

ranks 라는 빈 딕셔너리를 생성시킨 후, enumerate함수를 통해 위에서 정렬시킨 names 리스트의 메뉴명에 순위를 매겼다.

이를 컴프리헨션을 이용해 한 줄로 줄이면 다음과 같다.

>>> ranks2 = {name:i for i, name in enumerate(names,1)}
>>> ranks2
{'감자탕': 1, '순대모듬': 2, '김치찌개': 3, '된장찌개': 4, '해장국': 5}

※ 참고로, enumerate는 주로 for문과 같이 쓰이며, 순차적인 정수와 리스트의 인수값을 쌍으로 반환하는 함수다. 반환하는 정수는 0이 기본값이며 두번째 인수값을 통해 시작점을 0이 아닌 다른 숫자를 정할 수 있다. 아래 예시는 정수를 5부터 반환하게끔 설정했다.

>>> for i, name in enumerate(names,5):
...     print(f'i = {i} / name = {name}')
...
i = 5 / name = 감자탕
i = 6 / name = 순대모듬
i = 7 / name = 김치찌개
i = 8 / name = 된장찌개
i = 9 / name = 해장국
  • 1순위 출력하기
>>> next(iter(ranks))
'감자탕'

딕셔너리를 이터레이터로 변환후 next 함수를 통해 첫번째 값을 반환했다.

이처럼 한 이유는 딕셔너리에서는 보통 key를 통해 value를 찾기 마련인데, 지금 메뉴명이 key, 순위가 value에 있으므로 value를 통해 key를 찾을 수 없기 때문에 이터레이터로 변환한다음에 next 함수를 쓰면 딕셔너리의 첫번째 key부터 순차적으로 반환하기 때문이다.

이를 함수로 구현하면 다음과 같다.

  • 함수로 구현
>>> def rank_system(sample_dit):
...     key_list = list(sample_dit.keys())
...     key_list.sort(key = sample_dit.get, reverse = True)
...     rank = {}
...     for i, key in enumerate(key_list,1):
...         rank[key] = i
...     return rank
...
>>> def get_first(x):
...     print( next(iter(x)))
...
>>> rank_system(menu)
{'감자탕': 1, '순대모듬': 2, '김치찌개': 3, '된장찌개': 4, '해장국': 5}
>>> xx = rank_system(menu)
>>> get_first(xx)
감자탕

 

반응형

댓글