Python 기초

파이썬에서 정렬하기

파이썬 리스트는 sort()라는 메소드를 가지고 이 메소드는 리스트를 정렬된 상태로 변경합니다.

또 sorted()라는 내장 함수는 이터러블 객체로부터 정렬된 리스트를 생성합니다. 여기서는 파이썬에서 정렬에 대하여 알아야 할 사항들을 요약해봅니다.

이 절의 내용을 작성할 때 https://wiki.python.org/moin/HowTo/Sorting 의 문서를 참조하였습니다.

만약 정렬 알고리즘을 스스로 구현해야 한다면 추후 다룰 '정렬' 장을 참조하시기 바랍니다.

 

간단하게 정렬을 실행하려면 아주 쉽습니다. 아래와 같이 sorted()를 호출하면 됩니다.

sorted() 는 기존의 리스트를 변경하는 것이 아니라 정렬된 새로운 리스트를 반환합니다. 기존의 리스트는 전혀 변경되지 않습니다.

print(sorted([4, 2, 3, 5, 1]))

 

<실행 결과>

[1, 2, 3, 4, 5]

 

리스트의 메소드인 sort()를 사용하여도 정렬이 됩니다. 이 경우에는 리스트 자체를 변경해버립니다. 일반적으로 이것보다는 내장 함수인 sorted()가 더 편리합니다.

myList = [4, 2, 3, 5, 1]
myList.sort()
print(myList)

 

<실행 결과>

[1, 2, 3, 4, 5]

 

또한 sort()는 리스트만을 위한 메소드이지만 sorted() 함수는 어떤 이터러블 객체도 받을 수 있습니다. 예를 들어서 다음과 같은 딕셔너리 객체도 받을 수 있습니다.

print(sorted({3 : 'D', 2 : 'B', 5 : 'B', 4 : 'E', 1 : 'A'}))

 

<실행 결과>

[1, 2, 3, 4, 5]

 

key 매개변수

key 매개변수가 많이 사용되는 경우는 객체의 데이터 중에서 특정한 데이터를 기준으로 정렬하는 경우입니다.

예를 들어서 학생들을 다음과 같이 튜플의 리스트로 나타낸 후에 학생들의 학번을 기준으로 정렬하는 코드를 작성하는 경우를 살펴봅시다.

students = [
    ('김태민', 0.12, 2018102186),
    ('김봉민', 3.14, 2017103969),
    ('김현우', 4.3, 2015104167)
    ]

print(sorted(students, key = lambda students : students[2]))

 

<실행 결과>

[('김현우', 4.3, 2015104167), ('김봉민', 3.14, 2017103969), ('김태민', 0.12, 2018102186)]

 

lambda는 람다식을 나타낸 것으로 정렬을 하기 전에 호출되는 함수를 나타낸 것으로 student 요소를 받아서 student[2]를 반환합니다. 즉 정렬의 기준이 학생들의 학번이 되는 것입니다.

 

위와 유사하게 학생들을 클래스로 표현하고 클래스의 인스턴스 변수를 정렬의 기준으로 지정하여도 됩니다.

class Student:
    def __init__(self, name, grade, number):
        self.name = name
        self.grade = grade
        self.number = number
    def __repr__(self):
        return repr((self.name, self.grade, self.number))

students = [
    Student('김태민', 0.12, 2018102186),
    Student('김봉민', 3.14, 2017103969),
    Student('김현우', 4.3, 2015104167)
    ]

print(sorted(students, key = lambda Student : Student.number))

 

<실행 결과>

[('김현우', 4.3, 2015104167), ('김봉민', 3.14, 2017103969), ('김태민', 0.12, 2018102186)]

 

오름차순 정렬과 내림차순 정렬

list.sort()와 내장함수 sorted()는 모두 reverse 매개변수를 받습니다. reverse 변수는 부울형으로 True이면 내림차순이 됩니다.

위의 예제에서 내림차순으로 정렬하려면 아래와 같습니다.

class Student:
    def __init__(self, name, grade, number):
        self.name = name
        self.grade = grade
        self.number = number
    def __repr__(self):
        return repr((self.name, self.grade, self.number))

students = [
    Student('김태민', 0.12, 2018102186),
    Student('김봉민', 3.14, 2017103969),
    Student('김현우', 4.3, 2015104167)
    ]

print(sorted(students, key = lambda Student : Student.number, reverse = True))

 

<실행 결과>

[('김태민', 0.12, 2018102186), ('김봉민', 3.14, 2017103969), ('김현우', 4.3, 2015104167)]

 

정렬의 안정성

파이썬 버전 2.2부터 파이썬에서의 정렬은 안정성이 보장됩니다.

안정성이란 동일한 키를 가지고 있는 레코드가 여러 개 있을 때 정렬 후에도 레코드들의 원래 순서가 유지되는 것을 의미합니다.

data = [(1, 200), (1, 100), (2, 300), (2, 400)]
print(sorted(data, key = lambda item : item[0]))

 

<실행 결과>

[(1, 200), (1, 100), (2, 300), (2, 400)]

 

위의 코드에서 (1, 100) 레코드와 (1, 200) 레코드가 정렬 후에도 위치가 변경되지 않았습니다. 이것은 사소한 것 같지만 중요할 수도 있습니다.

예를 들어 대학교에서 신입생을 선발할 때, 성적이 같으면 선착순으로 선발한다고 합시다. 이때는 반드시 정렬의 안정성이 보장되어야 합니다.

 

도전 과제

주소록을 작성한다고 합시다. 간단하게 사람들의 이름과 나이만 저장하고자 할 때 사람을 Person 이라는 클래스로 나타냅니다. Person 클래스는 아래와 같은 인스턴스 변수를 가집니다.

  • name : 이름을 나타냅니다. (문자열)
  • age : 나이를 나타냅니다. (정수형)

 

나이순으로 정렬하여 보여주는 프로그램을 작성해봅시다. 정렬의 기준은 사람의 나이입니다. 사람의 정보는 아래와 같으며 정렬 후 리스트로 나열합니다.

  • name - 김현우, age - 22
  • name - 김봉민, age - 20
  • name - 강슬기, age - 25

 

<실행 결과>

[< 이름 : 김봉민, 나이 : 20>, < 이름 : 김현우, 나이 : 22>, < 이름 : 강슬기, 나이 : 25>]