초보 개발자

19강 정렬 기술 sort, sorted, key 본문

Python/윤성우 열혈 파이썬

19강 정렬 기술 sort, sorted, key

taehyeki 2022. 1. 17. 17:30

[리스트의 sort 메소드]

 

ns = [3,1,4,2]
ns.sort() #기본 오름차순
ns
[1,2,3,4]

ns.sort(reverse=True)
ns
[4,3,2,1]

내부적으로 모든 값을 대상으로 <또는 > 연산을 진행하고 그 결과를 바탕으로 오름차순 정렬을 한다.
내림차순 정렬을 원한다면 매개변수 rever에 True를 전달하면 된다.

 

그럼 다음과 같이 이름과 나이 정보가 묶여 있는 상황에서는 어떻게 정렬을 진행해야 할까?

 

ns = [('Yoon',33),('Lee',12),('Park',29)] # (name, age)

이건 상황에 따라 달라진다. 이름이 기준인지, 나이가 기준인지,

먼저 나이를 기준으로 정렬을해보자

 

ns = [('Yoon',33),('Lee',12),('Park',29)] # (name, age)

def age(t): # t는 튜플
	return t[1] #나이 반환하는 함수
    

ns.sort(key = age) # 매개변수 key에 함수 age를 전달
ns
[('Lee',12),('Park',29),('Yoon',33

ns.sort(key = age, reverse=True) # reverse=True를 주면 내림차순으로된다.
ns
[('Lee',12),('Park',29),('Yoon',33)]

튜플의 1번째 인덱스가 나이니까 나이를 반환하는 함수를 만들고, sort의 매개변수 key에 만든 함수를 넣어주자

함수는 객체이니까 가능하다. 그럼 각 리스트의 요소를 하나하나씩 넣고 그 값을 바탕으로 정렬한다.

 

t[0]을 반환하면 이름순으로 정렬할 것이다.

 

 

람다를 활용해서 보다 간편하게 작성할 수 있다. 전달되는 인자를 t로 받고 t[1]을 반환하는 람다를 사용해보자

ns = [('Yoon',33),('Lee',12),('Park',29)] # (name, age)
ns.sort(key = lambda t : t[1], reverse =True) # 이름의 알파벳 역순으로 정렬
ns
[('Yoon',33),('Park',29),('Lee',12)]

이를 응용해보면 글자 길이기준으로 정렬하려면 key에 len함수를 넣으면 된다, 그럼 각 요소가 len의 인자로 들어가고 그 값을 기준으로 정렬한다.

names = ['Julia','Yoon','Steven']
names.sort(key=len)
names
['Yoon','Julia','Steven']

 

이번엔 튜플의 합을 기준으로 정렬해보자

nums = [(3, 1),(2, 9),(0, 5)] # 두 수의 합은 각각 4, 11 , 5이다

nums.sort(key = lambda x : x[0] + x[1], reverse=True)
nums
[(2, 9),(0, 5),(3, 1)]

 

[sorted 함수 사용하기]

 

sort는 메소드이다. 리스트에 내장되어있는 함수이다. 리스트 자체를 수정해버린다. 즉 원본이 바뀐다.

하지만 sorted는 함수이다. 그리고 정렬한 값을 return 한다. 즉 원본은 그대로 있다.

 

org = [('Yoon',33),('Lee',12),('Park',29)] 
cpy = sorted(org, key = lambda t : t[1], reverse = True)
org # 원본 유지
[('Yoon',33),('Lee',12),('Park',29)] 
cpy # 정렬된 사본 생성
[('Park',29),('Lee',12),('Yoon',33)]

 

튜플에는 sort메소드가 존재하지 않는다. 이유는 이뮤터블 객체이니까!! 수정할 수 없다. 하지만 sorted함수는 정렬된 사본을 새로 생성하기 때문에, literable객체이면 인자로 무엇이든지 전달할 수 있다. (뮤터블 이뮤터블 상관 x)

원본을 그대로 두고 정렬 결과로 새로운 값을 반환한다.

단 리스트에 담아서 반환이 된다.