Python-객체의 속성을 기반으로 객체 목록을 정렬하는 방법은 무엇입니까?



소프트웨어 엔지니어링 경력에서 중요하지 않은 항목 목록을 정렬해야 하는 경우를 놓치지 않을 것입니다. 숫자, 문자열 또는 개체가 될 수 있습니다. 객체 목록을 정렬하는 데 필요한 문제에 직면한 적이 있습니다. 다음은 정렬해야 하는 직원 목록(직원은 이름, 직원 번호 및 급여의 3가지 속성을 가짐)의 좋은 예입니다. 이름, 직원 번호 또는 급여로 정렬할 수 있습니다.

employees = [ 
      Employee('Dave', 173, 122000),        
      Employee('Dyke', 172, 122000),        
      Employee('Jake', 124, 142000),        
      Employee('John', 143, 95000),        
      Employee('Jane', 193, 100000),   
]


이런 종류의 문제에 대한 솔루션을 작업하는 동안 나는 두 가지 솔루션을 얻었습니다. 내 초기 솔루션에는 두 개의 루프가 있었고 각 루프에는 느리고 읽기 어려운 중첩 루프가 있었습니다. 효율적이고 읽기 쉬운 접근 방식을 찾기 위해 인터넷 검색을 한 후 Python 문서에 도달했습니다. 목록뿐만 아니라 튜플의 개체를 정렬하는 더 깔끔한 방법을 발견했습니다. sorted(iterable, key=None, reverse=False) 또는 list.sort()를 사용하여 파이썬에서 목록을 정렬할 수 있습니다. 이 글은 위의 문제를 정렬하기 위한 정렬에 적용됩니다. Sorted는 가져올 필요가 없는 파이썬 내장 함수입니다.

숫자 또는 문자열 목록을 정렬하는 간단한 예부터 시작하겠습니다. 값을 오름차순으로 정렬하려면 iterables를 정렬된 함수에 전달하기만 하면 됩니다. 키워드 인수 reverse=False를 전달하거나 생략할 수 있습니다.

sorted([5, 1, 2, 4, 3]) # returns [1, 2, 3, 4, 5]
sorted([5, 1, 2, 4, 3], reverse=False) # returns [1, 2, 3, 4, 5]


내림차순으로 값을 정렬하려면 정렬된 함수의 두 번째 인수로 reverse=True를 전달해야 합니다.

sorted([5, 1, 2, 4, 3], reverse=True) # returns [5, 4, 3, 2, 1]


Sorted는 iterable의 항목에서 새로 정렬된 목록을 반환합니다. 이 함수는 세 개의 인수를 취합니다. 키워드 인수로 지정해야 하는 키와 역방향은 위의 코드와 같이 선택 사항입니다. python 문서에 따르면 키는 iterable의 각 요소에서 비교 키를 추출하는 데 사용되는 하나의 인수 함수를 지정합니다. 예를 들어 key=str.lower를 비교하는 동안 모든 목록 값을 더 낮게 변경해야 합니다. reverse는 부울 값으로 True로 설정하면 각 비교가 반대(내림차순)인 것처럼 요소 목록이 정렬됩니다.

이제 객체의 하나 이상의 속성을 기반으로 위에 주어진 객체 목록을 어떻게 정렬합니까? 생성할 수 있는 객체의 클래스를 정의하는 것으로 시작하겠습니다. 파이썬에는 operator , itemgetter()attrgetter() 을 제공하는 methodcaller() 모듈이 있으므로 우리에게 도움이 될 것입니다.

class Employee: 

    def __init__(self, name, staff_no, salary):        
        self.name = name        
        self.staff_no = staff_no        
        self.salary = salary 

    def __repr__(self):        
        return repr((self.name, self.staff_no, self.salary))
if __name__ == '__main__': 

   employees = [        
      Employee('Dave', 173, 122000),        
      Employee('Dyke', 172, 122000),        
      Employee('Jake', 124, 142000),        
      Employee('John', 143, 95000),        
      Employee('Jane', 193, 100000),    
   ]


하나의 속성(예: 급여)을 기준으로 오름차순으로 정렬

employees = sorted(employees, key=lambda employee:employee.salary)
# returns [('John', 143, 95000), ('Jane', 193, 100000), ('Dave', 173, 122000), ('Dyke', 172, 122000), ('Jake', 124, 142000)]


하나의 속성(예: 급여)을 기준으로 내림차순으로 정렬

employees = sorted(employees, key=lambda employee:employee.salary, reverse=True)
# returns[('Jake', 124, 142000), ('Dave', 173, 122000), ('Dyke', 172, 122000), ('Jane', 193, 100000), ('John', 143, 95000)]


둘 이상의 속성으로 정렬하기 위해 attrgetter(attr_name_1, attr_name_2)를 키 값으로 사용합니다. 즉, 첫 번째 속성 값이 같으면 두 번째 속성 값을 사용하여 비교합니다.

employees = sorted(employees, key=attrgetter('salary', 'staff_no'))
# [('John', 143, 95000), ('Jane', 193, 100000), ('Dyke', 172, 122000), ('Dave', 173, 122000), ('Jake', 124, 142000)]


실제 속성을 사용하는 대신 객체 튜플에서 속성의 인덱스 위치를 사용할 수 있습니다.

employees = [
        ('Dave', 173, 122000),
        ('Dyke', 172, 122000),
        ('Josh', 172, 130000),
        ('Jake', 124, 142000),
        ('John', 143, 95000),
        ('Jane', 193, 100000),
    ]
sorted(employees, key=itemgetter(1,2)) //sort by staff_number first, then salary
# [('Jake', 124, 142000), ('John', 143, 95000), ('Dyke', 172, 122000), ('Josh', 172, 130000), ('Dave', 173, 122000), ('Jane', 193, 100000)]


의견을 보내 주셔서 감사합니다.

좋은 웹페이지 즐겨찾기