본문 바로가기
카테고리 없음

[Python] 파이썬 정렬 sorted() 함수 사용법 및 예제

by A6K 2022. 11. 5.

파이썬에서는 리스트에 들어있는 엘리먼트들을 정렬할 수 있는 sorted() 함수를 제공하고 있다. sorted() 함수는 파이썬 내장 함수로 데이터를 정렬해서 새로운 리스트로 만들어 반환해준다.

리스트 자료형에서 제공하는 sort()와 유사하다. 리스트 자료형에서 제공하는 메소드인 sort()는 리스트 객체 내부에서 순서를 바꿔주는 반면 sorted() 함수는 새로운 리스트로 만들어서 리턴해준다.

sorted() 함수 - 리스트 정렬

sorted() 함수를 이용해서 리스트를 정렬하는 예제를 살펴보자.

a = [2,7,3,6,4]
b = sorted(a)

print(a)
print(b)

# [2, 7, 3, 6, 4]
# [2, 3, 4, 6, 7]

sorted() 함수에 a 변수의 리스트를 넘겨주면 a 리스트 내부에 있는 엘리먼트들을 정렬해서 새로운 리스트로 리턴해준다. 따라서 리턴되는 값을 담는 b와 인자로 넘겨준 a는 서로 다른 리스트 객체다.

참고로 리스트 자료형에서 제공하는 sort() 함수는 리스트 객체 자체를 정렬시켜준다.

a = [2,7,3,6,4]
a.sort()

print(a)

# [2, 3, 4, 6, 7]

만약 정렬하기 애매한 데이터가 들어가있는 경우라면 에러가 발생한다. 예를 들어 문자열 데이터와 숫자 데이터가 하나의 리스트에 함께 들어있는 경우라면 TypeError가 발생한다.

a = ["a", "b", 1, 2]
b = sorted(a)

print(b)

# Traceback (most recent call last):
#   File "./test.py", line 5, in <module>
#     b = sorted(a)
# TypeError: '<' not supported between instances of 'int' and 'str'

숫자 데이터와 문자데이터를 직접 비교하는게 애매하기 때문이다. sorted() 함수에 사용되는 입력 인자에 들어있는 엘리먼트들은 반드시 논리적으로 비교 가능해야한다.

또 다른 에러로는 엘리먼트로 None이 들어있는 경우다.

a = ["a", "d", None, "c"]
b = sorted(a)

print(b)

# Traceback (most recent call last):
#   File "./test.py", line 5, in <module>
#     b = sorted(a)
# TypeError: '<' not supported between instances of 'NoneType' and 'str'

None 값은 어떤 데이터와도 대소 비교를 할 수 없기 때문에 이런 에러가 발생한다.

역순정렬 - reverse

sorted() 함수는 엘리먼트를 오름차순으로 정렬한다. 내림차순으로 정렬하기 위해서는 reverse 파라미터의 값을 True로 설정하면된다.

예를들어보자.

orig = [2,7,3,6,4]
asc = sorted(orig)
desc = sorted(orig, reverse=True)

print(orig)
print(asc)
print(desc)

# [2, 7, 3, 6, 4]
# [2, 3, 4, 6, 7]
# [7, 6, 4, 3, 2]

그냥 sorted() 함수를 사용하면 오름차순으로 정렬하지만 reverse 파라미터를 True로 설정하면 내림차순으로 정렬된 리스트가 리턴된다.

특정 값을 기준으로 정렬 - key

리스트에 들어있는 데이터가 문자나 숫자 데이터 같은 간단한 데이터가 아닌 특정 클래스의 객체나 딕셔너리일 수도 있다. 이 경우 어떤 값을 기준으로 정렬을 할지 key 파라미터를 이용해서 지정할 수 있다.

예를 들어 다음과 같은 데이터가 있다고 해보자.

members = [
  {'name': 'Kim', 'age': 23},
  {'name': 'Lee', 'age': 73},
  {'name': 'Choi', 'age': 12},
  {'name': 'Park', 'age': 52},
  {'name': 'Lim', 'age': 43}
]

멤버들의 정보가 있는 딕셔너리들을 담고 있는 member 리스트다. 이 리스트를 멤버들의 나이를 기준으로 정렬하고 싶다고 하자.

단순하게 sorted() 함수에 member 변수를 넘기면 에러가 발생한다.

members = [
  {'name': 'Kim', 'age': 23},
  {'name': 'Lee', 'age': 73},
  {'name': 'Choi', 'age': 12},
  {'name': 'Park', 'age': 52},
  {'name': 'Lim', 'age': 43}
]

sorted(members)

# Traceback (most recent call last):
#   File "./test.py", line 12, in <module>
#     sorted(members)
# TypeError: '<' not supported between instances of 'dict' and 'dict'

딕셔너리 객체와 딕셔너리 객체는 비교 할 수 없기 때문에 이런 에러가 발생한다.

앞서 정렬기준을 딕셔너리가 아닌 딕셔너리에 들어있는 멤버의 나이 값을 기준으로 삼고 싶다고 했다. 딕셔너리에서 이 정보를 가져올 수 있는 방법을 sorted() 함수의 key 파라미터에 넘겨주면 된다.

파이썬의 람다를 이용해서 딕셔너리의 age 값을 뽑아와서 정렬 기준으로 삼을 수 있도록 다음과 같이 수정할 수 있다.

members = [
  {'name': 'Kim', 'age': 23},
  {'name': 'Lee', 'age': 73},
  {'name': 'Choi', 'age': 12},
  {'name': 'Park', 'age': 52},
  {'name': 'Lim', 'age': 43}
]

a = sorted(members, key=lambda member: member['age'])

print(a)

# [{'name': 'Choi', 'age': 12}, {'name': 'Kim', 'age': 23}, {'name': 'Lim', 'age': 43}, {'name': 'Park', 'age': 52}, {'name': 'Lee', 'age': 73}]

sorted() 함수는 정렬의 기준이 되는 값을 찾아내기 위해 key 파라미터로 넘겨진 정보를 이용한다. 비교 대상 엘리먼트인 딕셔너리를 받아서 member 변수에 취하고, member 변수를 이용해서 member['age']로 접근한 값을 키 값으로 삼아 정렬을 진행하게 된다.

그 결과 멤버들의 나이값을 기준으로 오름차순 정렬된 데이터가 리턴되는 것을 확인할 수 있다.

흥미로운 예제를 또 하나 살펴보자. 리스트에 숫자 데이터와 문자로 표현된 숫자데이터가 혼재하고 있는 상황을 보자.

numbers = [6, 4, "2", 3, "1"]

a = sorted(numbers)

# Traceback (most recent call last):
#   File "./test.py", line 5, in <module>
#     a = sorted(numbers)
# TypeError: '<' not supported between instances of 'str' and 'int'

위에서 설명했던 것처럼 숫자데이터와 문자데이터는 직접 비교할 수 없기 때문에 TypeError가 발생한다. numbers 리스트를 정렬하기 위해서는 비교가 가능하도록 만들어줘야한다.

key 파라미터를 int로 넘겨주면 문자열 데이터를 숫자로 캐스팅해서 비교한 다음 정렬해준다.

numbers = [6, 4, "2", 3, "1"]

a = sorted(numbers, key=int)
print(a)

# ['1', '2', 3, 4, 6]

숫자로 타입 전환을 한 다음 비교를 한다. 원본 데이터가 바뀌지는 않아서 sorted() 함수의 결과로 리턴된 리스트에서 '2'와 '1' 엘리먼트는 여전히 문자타입으로 표현되고 있다. 


 

파이썬 스크립트 작성에 도움되는 글 모음

파이썬으로 프로그램을 작성할 때 도움되는 글들을 모아본다. 개발환경 [Python] macOS에 파이참 설치 [Python] 파이참 깃허브 연동 [Python] 파이썬 PIP란? [Python] VSCode를 이용한 개발환경 [Python] python3를

hbase.tistory.com

 

댓글