알고리즘

[Python] lambda 함수 사용법

히치하이커 J 2024. 10. 18. 16:47
반응형

객체 정렬에서는 lambda 함수의 반환값에 기준이 되기를 원하는 값을 적어줍니다. sort 함수에서 key 인자로 lambda 함수를 작성하였을 때 x인자에 들어오는 값은 하나의 객체 이기 때문에, 이 객체의 국어 점수에 해당하는 x.kor를 적어주면, 국어 점수를 기준으로 오름차순으로 정렬을 진행하게 됩니다.

class Student:
    def __init__(self, kor, eng, math):
        self.kor = kor
        self.eng = eng
        self.math = math

students = [
    Student(90, 80, 90), # 첫 번째 학생
    Student(20, 80, 80), # 두 번째 학생
    Student(90, 30, 60), # 세 번째 학생
    Student(60, 10, 50), # 네 번째 학생
    Student(80, 20, 10), # 다섯 번째 학생 
]

students.sort(key=lambda x: x.kor) # 국어 점수 기준 오름차순 정렬

for student in students: # 정렬 이후의 결과 출력
    print(student.kor, student.eng, student.math)

>> 20 80 80
   60 10 50
   80 20 10
   90 80 90
   90 30 60
이렇게 국어 점수를 기준으로 오름차순으로 정렬이 됩니다. 이때 국어 점수가 90점으로 동일한 두 학생의 경우에는, 어떤 학생이 더 앞서서 나오게 되는지는 모호하므로 이런 경우에는 보다 더 명확한 기준이 필요할 수 있습니다.

국어 점수를 기준으로 내림차순 정렬을 해볼 수는 없을까요? 앞서 배운 reversed 함수를 사용할 수도 있겠지만, lambda 함수에서 x.kor 앞에 -를 붙여 해결하는 것이 일반적입니다. x.kor로 정렬을 하면 오름차순이 되므로, 정수 값에 전부 -를 붙여 오름차순으로 정렬하라는 얘기는 곧 점수 기준으로 내림차순 정렬을 하라는 얘기와 같습니다. 이 방법을 실제로 가장 많이 사용합니다.

class Student:
    def __init__(self, kor, eng, math):
        self.kor = kor
        self.eng = eng
        self.math = math

students = [
    Student(90, 80, 90), # 첫 번째 학생
    Student(20, 80, 80), # 두 번째 학생
    Student(90, 30, 60), # 세 번째 학생
    Student(60, 10, 50), # 네 번째 학생
    Student(80, 20, 10), # 다섯 번째 학생 
]

students.sort(key=lambda x: -x.kor) # 국어 점수 기준 내림차순 정렬

for student in students: # 정렬 이후의 결과 출력
    print(student.kor, student.eng, student.math)

>> 90 80 90
   90 30 60
   80 20 10
   60 10 50
   20 80 80
그렇다면 왜 굳이 객체 정렬을 사용해야만 할까요?

다음과 같이 학생의 국어, 영어, 수학 점수를 다 따로 관리했다고 생각해봅시다. 이때 국어 점수를 오름차순으로 정렬하게 된다면, 당연히 다른 과목 점수들도 해당 학생의 순서가 바뀜에 따라 같이 움직이기를 바랄 것입니다. 하지만 국어, 영어, 수학 점수는 다 따로 리스트를 통해 관리되고 있기 때문에, 국어 점수만 정렬이 될 뿐 다른 점수들은 처음 정의된 값을 그대로 갖고 있게 됩니다. 따라서 원하는 결과를 얻을 수 없습니다.

kors = [90, 20, 90, 60, 80]
engs = [80, 80, 30, 10, 20]
maths = [90, 80, 60, 50, 10]

kors.sort()

print(kors)  # [20, 60, 80, 90, 90]
print(engs)  # [80, 80, 30, 10, 20]
print(maths) # [90, 80, 60, 50, 10]

반응형