[파이썬] sort(), sorted() 완벽정리

InAnarchy·2023년 4월 12일
1

Python

목록 보기
4/14
post-thumbnail

sort()와 sorted()의 차이점

sort()

  • 기존의 리스트를 정렬한다(modifies the list in-place)
  • 리스트 내에서만 정의될 수 있다(list.sort() method is only defined for lists)
a = [5, 2, 3, 1, 4]
a.sort()
a #[1, 2, 3, 4, 5]

sorted()

  • 새로운 정렬된 리스트를 만든다.(builds a new sorted list from an iterable)
  • the sorted() function accepts any iterable.
sorted([5, 2, 3, 1, 4]) #[1, 2, 3, 4, 5]
sorted({1: 'D', 2: 'B', 3: 'B', 4: 'E', 5: 'A'}) #[1, 2, 3, 4, 5]

sort()와 sorted()의 공통점

key 매개변수

print(sorted("This is a test string from Andrew".split())) #['Andrew', 'This', 'a', 'from', 'is', 'string', 'test']
print(sorted("This is a test string from Andrew".split(), key=str.lower)) #['a', 'Andrew', 'from', 'is', 'string', 'test', 'This']

처음에는 공백을 기준으로만 정렬하니 대문자 오름차순->소문자 오름차순 순서로 나왔다.
그런데 key에 str.lower을 설정하여 대소문자를 구분하지 않고 비교했다.

참고로 이 때는 sorted를 사용했으므로 원본 리스트는 바뀌지 않는다.

sort()를 사용해 다시 정렬해보자. 결과는 같다.

student_tuples.sort(key=lambda student: student[2])   # sort by age

이 때는 원본의 리스트가 바뀐다!

위의 경우에는 student[2] 인덱스였지만
아래처럼 속성을 통해서 적용할 수도 있다.

class Student:
    def __init__(self, name, grade, age):
        self.name = name
        self.grade = grade
        self.age = age
    def __repr__(self):
        return repr((self.name, self.grade, self.age))
student_objects = [
    Student('john', 'A', 15),
    Student('jane', 'B', 12),
    Student('dave', 'B', 10),
]
sorted(student_objects, key=lambda student: student.age) #[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]

Operator Module

해당 모듈에 대한 공식 문서 링크는 하단의 reference에 링크를 걸어두었다.

sorted(student_objects, key=lambda student: student.age) 

위 코드를 더 간단하게 해보자.

from operator import itemgetter, attrgetter

print(sorted(student_tuples, key=itemgetter(2))) #[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
print(sorted(student_objects, key=attrgetter('age'))) #[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]

물론 sort()도 사용할 수 있다.

student_tuples.sort(key=itemgetter(2))
print(student_tuples)

student_objects.sort(key=attrgetter('age'))  # sort by age
print(student_objects)

위의 경우에는 나이를 기준으로만 정렬했는데, 다음의 코드를 보자.

print(sorted(student_tuples, key=itemgetter(1,2))) #학년별->연령별[('john', 'A', 15), ('dave', 'B', 10), ('jane', 'B', 12)])
print(sorted(student_objects, key=attrgetter('grade', 'age'))) #마찬가지

student_tuples.sort(key=itemgetter(1, 2))
print(student_tuples)

student_objects.sort(key=attrgetter('grade', 'age'))
print(student_objects)

If multiple items are specified, returns a tuple of lookup values.

오름차순, 내림차순 정렬

  • reverse 매개변수에서 True로 설정 시 내림차순, False로 설정 시 오름차순이다. 디폴트는 False.
print(sorted(student_tuples, key=itemgetter(2), reverse=True))
print(sorted(student_tuples, key=itemgetter(2), reverse=False))
print(sorted(student_tuples, key=itemgetter(2)))
[('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]

2차원 배열의 정렬

행 기준 정렬

list = [[1,2], [1,3],[0,5],[5,1],[4,3]] 
print(sorted(list, key = lambda x:x[0])) #[[0, 5], [1, 2], [1, 3], [4, 3], [5, 1]]
print(sorted(list, key = lambda x:x[0], reverse = True)) #[[5, 1], [4, 3], [1, 2], [1, 3], [0, 5]]

열 기준 정렬

list = [[1,2], [1,3],[0,5],[5,1],[4,3]] 
print(sorted(list, key = lambda x:x[1])) #[[5, 1], [1, 2], [1, 3], [4, 3], [0, 5]]
print(sorted(list, key = lambda x:x[1], reverse = True)) #[[0, 5], [1, 3], [4, 3], [1, 2], [5, 1]]

다중 조건 정렬

list.sort(key = lambda x: (x[1], x[0])) #두번째 값이 같을 경우 첫번째 값을 기준으로 오름차순 
list #[[5, 1], [1, 2], [1, 3], [4, 3], [0, 5]]
sorted(list, key=lambda x : (-x[0], x[1])) #첫번째 값은 내림차순, 두번째 값은 오름차순
#[[5, 1], [4, 3], [1, 2], [1, 3], [0, 5]]
sorted(list, key=lambda x:-x[0]) #첫번째 값을 오름차순
#[[5, 1], [4, 3], [1, 2], [1, 3], [0, 5]]

REFERNCE:
PYTHON DOCS

PYTHON DOCS

profile
github blog 쓰다가 관리하기 귀찮아서 돌아왔다

0개의 댓글