객체들을 저장한 iterable에서 객체들끼리 대소비교를 해야할때가 있습니다.

sorted, min, max 등의 함수를 이용할때 key 파라미터에 대소비교를 할 값을 리턴하는 함수를 줍니다.

이 함수는 비교할 객체 1개를 받아서 다른 객체들과 비교할 대소비교 가능한 값 하나를 리턴합니다.

하지만, 가끔은 C나 JAVA에서처럼 비교할 원소 2개를 입력받아 대소에 따라 음수, 0, 양수를 리턴하도록 하는 함수가 필요할 때도 있습니다.

그럴때 cmp_to_key를 사용하면 비교함수를 key에 줄 수 있습니다.

from functools import cmp_to_key

class Person:
    def __init__(self, name, weight, height):
        self.name = name
        self.weight = weight
        self.height = height
    def __repr__(self):
        return f"{self.name}(w: {self.weight}kg, h: {self.height}m)"

# weight를 기준으로 비교
def cmpByWeight(p1, p2):
    return p1.weight - p2.weight

# height을 기준으로 비교
def cmpByHeight(p1, p2):
    return p1.height - p2.height

# bmi를 계산하여 bmi를 기준으로 비교
def cmpByBMI(p1, p2):
    bmi1 = p1.weight / p1.height ** 2
    bmi2 = p2.weight / p2.height ** 2
    return bmi1 - bmi2

def main():
    people = [
        Person("A", 90, 1.7), Person("B", 60, 1.68), Person("C", 75, 1.55)
    ]

    byWeight = sorted(people, key=cmp_to_key(cmpByWeight))
    print(byWeight)
    # [B(w: 60kg, h: 1.68m), C(w: 75kg, h: 1.55m), A(w: 90kg, h: 1.7m)]


    byHeight = sorted(people, key=cmp_to_key(cmpByHeight))
    print(byHeight)
    # [C(w: 75kg, h: 1.55m), B(w: 60kg, h: 1.68m), A(w: 90kg, h: 1.7m)]
    
    byBMI = sorted(people, key=cmp_to_key(cmpByBMI))
    print(byBMI)
    # [B(w: 60kg, h: 1.68m), A(w: 90kg, h: 1.7m), C(w: 75kg, h: 1.55m)]

if __name__ == '__main__':
    main()

 

+ Recent posts