오브젝트 속성을 기반으로 오브젝트 목록을 정렬하려면 어떻게 해야 합니까?
각 객체의 특정 속성을 기준으로 정렬하는 Python 객체의 목록이 있습니다.
[Tag(name="toe", count=10), Tag(name="leg", count=2), ...]
목록을 정렬하려면 어떻게 해야 합니까?.count
내림차순으로?
목록을 정렬하려면:
orig_list.sort(key=lambda x: x.count, reverse=True)
새 목록을 반환하려면sorted
:
new_list = sorted(orig_list, key=lambda x: x.count, reverse=True)
설명:
key=lambda x: x.count
수순으로 정렬하다reverse=True
내림차순으로 정렬하다
가장 빠른 방법은, 특히 목록에 레코드가 많은 경우,operator.attrgetter("count")
다만, 이것은 Python의 프리오퍼레이터 버전에서는 동작하는 경우가 있기 때문에, 폴백 메카니즘이 있으면 좋을 것입니다.그러면 다음 작업을 수행할 수 있습니다.
try: import operator
except ImportError: keyfun= lambda x: x.count # use a lambda if no operator module
else: keyfun= operator.attrgetter("count") # use operator since it's faster than lambda
ut.sort(key=keyfun, reverse=True) # sort in-place
key= 메서드는 다음과 같습니다.
ut.sort(key=lambda x: x.count, reverse=True)
는 개체에 리치 비교 연산자를 추가하는 것보다 몇 배 더 빠릅니다.나는 이것을 읽고 놀랐다('호두껍질 속의 피톤' 485쪽).이것을 확인하려면 , 다음의 작은 프로그램으로 테스트를 실행합니다.
#!/usr/bin/env python
import random
class C:
def __init__(self,count):
self.count = count
def __cmp__(self,other):
return cmp(self.count,other.count)
longList = [C(random.random()) for i in xrange(1000000)] #about 6.1 secs
longList2 = longList[:]
longList.sort() #about 52 - 6.1 = 46 secs
longList2.sort(key = lambda c: c.count) #about 9 - 6.1 = 3 secs
저의 아주 최소한의 테스트 결과 첫 번째 종류는 10배 이상 느리지만, 책에는 일반적으로 5배 정도 느리다고 나와 있습니다.그 이유는 파이썬(timsort)에서 사용되는 고도로 최적화된 정렬 알고리즘 때문입니다.
그러나 .sort(lambda)가 일반 .sort()보다 빠르다는 것은 매우 이상합니다.고쳐졌으면 좋겠어요.
객체 지향 접근법
오브젝트 정렬 로직(해당하는 경우)을 각 인스턴스에 포함시키지 않고 클래스의 속성으로 하는 것이 좋습니다.
이를 통해 일관성이 보장되고 보일러 플레이트 코드가 필요하지 않습니다.
최소한 다음을 지정해야 합니다.__eq__
그리고.__lt__
이 작업을 수행할 수 있습니다.그럼 그냥 사용하세요sorted(list_of_objects)
.
class Card(object):
def __init__(self, rank, suit):
self.rank = rank
self.suit = suit
def __eq__(self, other):
return self.rank == other.rank and self.suit == other.suit
def __lt__(self, other):
return self.rank < other.rank
hand = [Card(10, 'H'), Card(2, 'h'), Card(12, 'h'), Card(13, 'h'), Card(14, 'h')]
hand_order = [c.rank for c in hand] # [10, 2, 12, 13, 14]
hand_sorted = sorted(hand)
hand_sorted_order = [c.rank for c in hand_sorted] # [2, 10, 12, 13, 14]
from operator import attrgetter
ut.sort(key = attrgetter('count'), reverse = True)
이는 Django ORM 모델 인스턴스 목록과 매우 유사합니다.
질의에 따라 다음과 같이 정렬하면 어떨까요?
ut = Tag.objects.order_by('-count')
개체 클래스에 리치 비교 연산자를 추가한 다음 목록의 sort() 메서드를 사용합니다.
비단뱀의 풍부한 비교를 볼 수 있습니다.
업데이트: 이 방법은 효과적이지만, Triptich의 솔루션이 훨씬 단순하기 때문에 귀사의 사례에 더 적합하다고 생각합니다.
정렬 기준 속성이 속성인 경우 가져오기를 피할 수 있습니다.operator.attrgetter
대신 자산의 메서드를 사용합니다.
예를 들어 클래스의 경우Circle
재산을 가지고radius
목록을 정렬할 수 있습니다.circles
다음과 같이 반지름에 의해:
result = sorted(circles, key=Circle.radius.fget)
이것은 가장 잘 알려진 기능은 아니지만 종종 Import에 대한 설명을 줄여줍니다.
또한 예를 들어 문자열과 숫자가 포함된 목록을 정렬하려는 경우.
eglist=[
"some0thing3",
"some0thing2",
"some1thing2",
"some1thing0",
"some3thing10",
"some3thing2",
"some1thing1",
"some0thing1"]
그 코드는 다음과 같습니다.
import re
def atoi(text):
return int(text) if text.isdigit() else text
def natural_keys(text):
return [ atoi(c) for c in re.split(r'(\d+)', text) ]
eglist=[
"some0thing3",
"some0thing2",
"some1thing2",
"some1thing0",
"some3thing10",
"some3thing2",
"some1thing1",
"some0thing1"
]
eglist.sort(key=natural_keys)
print(eglist)
언급URL : https://stackoverflow.com/questions/403421/how-do-i-sort-a-list-of-objects-based-on-an-attribute-of-the-objects
'programing' 카테고리의 다른 글
어레이의 각 루프에 대해를 사용하려면 어떻게 해야 합니까? (0) | 2023.04.10 |
---|---|
Swift 포함기존 UIKit 응용 프로그램의 UI 보기 (0) | 2023.04.10 |
Git에서 이전(마지막이 아님) 커밋에 변경된 파일을 추가하는 방법 (0) | 2023.04.10 |
현재 시각에 분수를 빠르게 추가하는 방법 (0) | 2023.04.10 |
iOS에서 디바이스 제조 및 모델을 얻는 방법 (0) | 2023.04.10 |