본문 바로가기
Python

Python - lambda 사용

by 희구리 2020. 12. 18.

최근 알고리즘 문제를 풀면서 정렬을 할 때 lambda를 많이 사용하고 있다.

 

단순한 1차원의 iterable(리스트, 튜플, 딕셔너리) 객체들은 sorted 혹은 sort 함수를 이용해서 정렬하면 되지만

2차원 이상의 객체들은 다양한 기준으로 정렬할 수 있기 때문에 lambda를 활용하면 매우 편리하다.

 

리스트(list) 또는 튜플(tuple)의 경우

example = [[1, 2], [2, 4], [3, 5], [7, 1]] 과 같은 2차원 리스트가 존재할 때 

첫 번째 원소를 기준으로 오름차순정렬하고 싶으면

sorted(example, key=lambda x: x[0])

>>> [[1, 2], [2, 4], [3, 5], [7, 1]]

위와 같이 코드를 입력하면 된다.

 

만약, 두 번째 원소를 기준으로 오름차순정렬하고 싶으면

sorted(example, key=lambda x: x[1])

>>> [[7, 1], [1, 2], [2, 4], [3, 5]]

x[0] 기준으로 설정했던 값을 x[1]로 바꿔주면 된다.

 

"즉, sorted(iterable한 객체, key=lambda x: x[기준이되는 인덱스] 형태로 작성하면 된다."

 

물론, 내부에 존재하는 리스트들의 길이가 각자 다를때 긴 리스트의 인덱스를 기준으로 설정하면 index error가 발생한다.

 

반대로 오름차순이 아닌 내림차순으로 설정하고 싶으면???

sorted(example, key=lambda x: -x[1])

>>> [[3, 5], [2, 4], [1, 2], [7, 1]]

기준을 정했던 값 앞에 '-'를 붙여주면 된다.

 

뿐만 아니라 lambda를 사용하면 다수의 기준으로 정렬할 수 있다.

첫 번째 원소의 값은 내림차순으로, 두 번째 원소의 값은 오름차순으로 정렬하고 싶으면

example = [[1, 2], [2, 4], [3, 6], [3, 5], [7, 3], [7, 1]]
sorted(example, key=lambda x: [-x[0], x[1]])

>>> [[7, 1], [7, 3], [3, 5], [3, 6], [2, 4], [1, 2]]

두 정렬 기준에 맞춰서 작성하면 된다.

이 때 주의해야할 점은 x[0], x[1] 원소들이 하나의 리스트 안에 담겨져 있기 때문에

다수의 정렬 기준을 적용할 때는 반드시 객체의 속성에 맞게 감싸줘야 한다.

 

※ 객체가 튜플(tuple)형태이면 어떻게 할까?

→ 튜플의 경우도 똑같다. 리스트와의 차이점은 괄호의 생김새일 뿐 사용하는 방법은 같다.

단, 튜플은 리스트와 달리 수정이 불가능한(immutable) 객체이기 때문에 (당연히)정렬 후 수정과 같은 작업은 할 수가 없다.


딕셔너리(dictionary)일 경우

딕셔너리는 key-value 쌍으로 이루어진 객체이기 때문에 간단하게 사용했던 리스트, 튜플과는 조금 다르다.

 

먼저 dictionary 객체의 내장함수를 사용하여 자료에 접근하는 방법은 아래와 같다.

dictionary = {"Classic" : 50, "Pop" : 25, "Jazz" : 30, "Dance" : 100 }

# 1. key값에 접근하기 - .keys()
dictionary.keys()

>>> dict_keys(['Classic', 'Pop', 'Jazz', 'Dance'])

# 2. value값에 접근하기 - .values()
dictionary.values()

>>> dict_values([50, 25, 30, 100])

# 3. key-value에 접근하기 - .items()
dictionary.items()

>>> dict_items([('Classic', 50), ('Pop', 25), ('Jazz', 30), ('Dance', 100)])

따라서, 내장함수를 이용하면 key와 value 또는 key-value에 해당하는 값을 정렬할 수 있다.

 

만약, key값을 정렬하고 싶으면? - 알파벳 오름차순

sorted(dictionary.keys(), key=lambda x: x[0])

>>> ['Classic', 'Dance', 'Jazz', 'Pop']

 

 

현재의 dictionary에서 value는 정수값 하나이다. 따라서 value값들을 내림차순으로 정렬하고 싶으면 아래와 같이 lambda를 사용하지 않고도 얻을 수 있다.

sorted(dictionary.values(), reverse=True)

>>> [100, 50, 30, 25]

 

하지만 파이썬의 dictionary 자료구조에서 value에는 하나의 정수 뿐만 아니라 리스트(list), 튜플(tuple) 등 다양한 값이 들어갈 수 있다.

 

아래와 같은 dictionary가 있다고 가정해보자.

music = {'classic': [1450, 500, 150, 800], 
	'pop': [3100, 600, 2500, 100], 
         'jazz': [2200, 300, 750, 200], 
         'dance': [1250, 5320, 2130, 5440]}

key마다 1차원 리스트를 value로 갖고 있는 형태이다.

 

만약 각 리스트에서 두 번째 원소값을 기준 내림차순으로 정렬했을 때 세 번째로 큰 값이 무엇인지 알고 싶으면 어떻게 해야할까?

sorted(music.values(), key=lambda x:-x[1])

>>> [[1250, 5320, 2130, 5440], [3100, 600, 2500, 100], [1450, 500, 150, 800], [2200, 300, 750, 200]]

다음과 같이 .values() 내장함수와 lambda를 사용해서 각 리스트들을 정렬할 수 있다.

 

두 번째 원소 값을 기준으로 정렬해보면 5320 > 600 > 500 > 300 순으로 500이 세 번째로 큰 값임을 알 수 있다.

 


💡 배운점

lambda 사용이 쉽지 않아 자주 사용하지 않았었다.

 

따라서, 다수의 기준으로 정렬하거나 원하는 값을 찾는 문제가 나올경우 단순히 반복문을 사용하여 원하는 값을 얻었는데

그렇다보니 코드가 지나치게 길어져 가독성이 좋지 못한 코드들이 많았다.

 

하지만, lambda를 잘 사용하면 가독성뿐만 아니라 코드를 간단하고 편리하게 작성할 수 있다.

※ 실제로 lambda는 정렬보다는 map, filter, reduce 함수와 쓰이는 걸로 많이 배운다.

 

사용할때마다 "어떻게 사용했더라?" 하면서 검색했었는데 이번 기회에 확실히 알아두고 가야겠다.

 

📖 (참고) lambda + 정렬을 이용해서 풀었던 문제들

[3차] 방금그곡 - Level2 : programmers.co.kr/learn/courses/30/lessons/17683

[3차] 파일명 정렬 - Level2 : programmers.co.kr/learn/courses/30/lessons/17686

베스트앨범 - Level3 : programmers.co.kr/learn/courses/30/lessons/42579

 

 

 

댓글