코테 입문 - lambda, sort, key

이동건·2024년 3월 18일

문제

이 문제를 접근하면서 처음엔 array.sort()를 넣지 않고 실행하였다.
그러하였더니 제한 사항 4번의 조건에 의해 에러가 발생하였고 그로 인
해 먼저 array.sort()를 진행하여 오름차순으로 만든후 빈 항인 answer에 abs, 차이의 절댓값을 넣는 방식에서 가장 작은 값을 출력하게 만들었다.

다른 풀이

#1
solution=lambda a,n:sorted(a,key=lambda x:(abs(x-n),x))[0]
#2
def solution(array, n):
    array.sort(key = lambda x : (abs(x-n), x-n))
    answer = array[0]
    return answer

1번 풀이와 2번풀이는 비슷한 식이지만 내가 이 풀이를 보았을 때 멘탈이 흔들렸다. 이게.. 이렇게 가능하다고? 이 풀이를 자세히 알기 위해 먼저 다음과 같은 걸 다시 공부해야 한다.

lambda

lambda 인자 : 표현식

람다 함수는 다음과 같은 방식으로 익명 함수(anonymous function)라 불린다. 람다 함수는 이름이 없는 함수로, 일반적으로 함수를 한 번만 사용하거나 함수를 인자로 전달해야 하는 경우에 매우 유용하게 사용된다.

map() 함수와 함께 사용

mylist = [1, 2, 3, 4, 5]
mylist2 = list(map(lambda x: x * 2, mylist))
print(mylist2)

map() 함수는 시퀀스(리스트, 튜플 등)의 모든 요소에 함수를 적용한 결과를 반환한다.
이 때, map() 함수와 함께 람다 함수를 사용하여 코드를 간결하게 작성한다.

filter() 함수와 함께 사용

filter() 함수는 시퀀스(리스트, 튜플 등)의 모든 요소 중에서 조건에 맞는 요소만을 반환한다. 이때, 'filter()' 함수와 함께 람다 함수를 사용하여 코드를 간결하게 작성할 수 있다.

mylist = [1, 2, 3, 4, 5]
mylist2 = list(filter(lambda x: x % 2 == 1, mylist))
print(mylist2) # [1,3,5]

sorted() 함수와 함께 사용

sorted() 함수는 시퀀스의 요소를 정렬한 결과를 반환한다. 다음과 같이 mylist가 있을 때 이 요소를 길이 순으로 정렬한 결과를 얻고 싶으면 아래와 같이 mylist2를 작성하면 된다.

mylist = ['apple', 'banana', 'cherry']
mylist2 = sorted(mylist, key=lambda x: len(x))
print(mylist2) #['apple', 'cherry', 'banana']

자주 사용되는 sorted(mylist, reverse=True)에서 reverse=True 자리에 key = ... 가 들어갔다 생각하면 된다.

reduce() 함수와 함께 사용

reduce()함수는 시퀀스의 모든 요소를 누적적으로 계산한 결과를 반환한다. 이때 reduce()함수와 함께 람다 함수를 사용하여 계산 방식을 지정할 수 있다.

from functools import reduce
mylist = [1, 2, 3, 4, 5]
result = reduce(lambda x, y: x * y, mylist)
print(result) #120

위 코드는 mylist 리스트의 모든 요소를 곱한 결과를 출력하는 코드이다.

etc - sort,sorted

변수.sort(), sorted(변수) 모두 정렬 기준은 문자열은 알파벳, 가나다순, 숫자는 오름차순이 기본값이다.

num_list = [15, 22, 8, 79, 10]
num_list.sort()
print(num_list)  # [8, 10, 15, 22, 79]

str_list = ['좋은하루','good_morning','굿모닝','niceday']
str_list.sort()
print(str_list) # ['good_morning', 'niceday', '굿모닝', '좋은하루']
print(sorted([15, 22, 8, 79, 10]))  # [8, 10, 15, 22, 79]
str_list = ['좋은하루','good_morning','굿모닝','niceday']
print(sorted(str_list))  # ['good_morning', 'niceday', '굿모닝', '좋은하루']

parameter (key, reverse)

  • reverse
    bool값을 넣는것으로 기본값은 reverse = False(오름차순)이다. reverse = True(내림차순)도 가능하다.
num_list = [15, 22, 8, 79, 10]
num_list.sort(reverse=True)
print(num_list)   # [79, 22, 15, 10, 8]
  • key
    정렬을 목적으로 하는 함수를 값으로 넣는다. lambda를 이용할 수 있고, key 값을 기준으로 정렬되고 기본값은 오름차순이다.
str_list = ['좋은하루','good_morning','굿모닝','niceday']
print(sorted(str_list, key=len))  # ['굿모닝', '좋은하루', 'niceday', 'good_morning']

print(sorted(str_list, key=lambda x : x[1])) # ['niceday', 'good_morning', '굿모닝', '좋은하루']

여러개의 요소를 가진 경우, 튜플로 사용가능하다.

tuple_list = [('좋은하루', 0),
    	      ('niceday', 1), 
    	      ('좋은하루', 5), 
    	      ('good_morning', 3), 
    	      ('niceday',5)]
tuple_list.sort(key=lambda x : (x[0], x[1]))  # '-'부호를 이용해서 역순으로 가능
print(tuple_list)
# [('good_morning', 3), ('niceday', 1), ('niceday', 5), ('좋은하루', 0), ('좋은하루', 5)]

문제 풀이 및 해석

#1
solution=lambda a,n:sorted(a,key=lambda x:(abs(x-n),x))[0]
#2
def solution(array, n):
    array.sort(key = lambda x : (abs(x-n), x-n))
    answer = array[0]
    return answer

다시 돌아오면 1번 풀이는 array대신 a로 받아들었고 n은 주어진 숫자이다.
먼저 큰 틀부터 보면 sorted(a,key = lambda x:(abs(x-n),x))[0]에서 주목할 점은 sorted(a, key이다. 이는 a(array)를 key의 조건으로 정렬하는 것이다.
다음은 key에 주어진 조건인데 key = lambda x:(abs(x-n),x))로 적혀있다. 여기서 짚고 넘어가야 할 것이 문제에서 절댓값 차이 순으로 배열 하는 것이기 때문에 abs(x-n) 만 써도 되지만 조건인 가장 가까운 수가 여러 개일 경우 더 작은 수를 return 합니다. 이를 만족하기 위해 같은 abs일 경우 x 값이 작은 수가 앞으로 오게 하는 것이다.
이 조건대로 a를 배열한 값의 [0]를 출력, 즉 n과 가장 가까우며 앞에 있는 값을 출력하는 것이다.

2번 풀이는 1번 풀이를 세줄로 나타낸 것인데, 1번풀이와 차이점은 (abs(x-n),x) 대신 (abs(x-n),x-n)를 사용한 것으로 결국 똑같은 이유다. 같은 절댓값일 경우 x-n에 의해 음수가 양수보다 앞에 오게 만든 것이다.
이렇게 해서 이해하지 못했던 문제풀이를 끝냈다.
아직 python를 하면서 lambda의 방식을 표현하는데 많은 어려움을 느낀다. 또한 numpy를 통한 해결 방식도 많이 공부 해야 할 필요가 있다.

profile
책 묵는 개발자

0개의 댓글