여러 속성을 기준으로 목록을 정렬하시겠습니까?
리스트가 있습니다.
[[12, 'tall', 'blue', 1],
[2, 'short', 'red', 9],
[4, 'tall', 'blue', 13]]
예를 들어 키 큰 요소/짧은 요소별로 정렬하려면s = sorted(s, key = itemgetter(1))
.
키/짧은 색과 짧은 색 모두로 정렬하고 싶다면 요소별로 1회씩 2회 정렬할 수 있는데, 더 빠른 방법은 없을까요?
키는 태플을 반환하는 함수일 수 있습니다.
s = sorted(s, key = lambda x: (x[1], x[2]))
또는 다음 방법으로 동일한 작업을 수행할 수 있습니다.itemgetter
(이것은 Python 함수 호출을 회피하고 고속입니다).
import operator
s = sorted(s, key = operator.itemgetter(1, 2))
그리고 여기서 사용할 수 있습니다.sort
사용하는 대신sorted
재할당:
s.sort(key = operator.itemgetter(1, 2))
이게 가장 버마적인 방법인지는 모르겠지만...첫 번째 정수값을 내림차순으로 정렬하고 두 번째 정수값을 알파벳 순으로 정렬해야 하는 튜플 목록이 있었습니다.이를 위해서는 정수 정렬을 반대로 해야 하지만 알파벳 정렬은 필요하지 않습니다.이것이 저의 해결책입니다. (시험 중에 저는 당신이 정렬된 함수를 '내스트'할 수 있는지조차 몰랐습니다.)
a = [('Al', 2),('Bill', 1),('Carol', 2), ('Abel', 3), ('Zeke', 2), ('Chris', 1)]
b = sorted(sorted(a, key = lambda x : x[0]), key = lambda x : x[1], reverse = True)
print(b)
[('Abel', 3), ('Al', 2), ('Carol', 2), ('Zeke', 2), ('Bill', 1), ('Chris', 1)]
파티에 몇 년 늦었지만 두 가지 기준에 따라 분류해서 사용하고 싶다.reverse=True
다른 사람이 방법을 알고 싶을 경우 기준(함수)을 괄호로 묶습니다.
s = sorted(my_list, key=lambda i: ( criteria_1(i), criteria_2(i) ), reverse=True)
사용하실 수 있을 것 같습니다.list
대신tuple
이것은 리스트/태플의 '매직 인덱스'가 아닌 속성을 잡을 때 더 중요하다고 생각합니다.
제 경우, 착신 키가 문자열인 클래스의 여러 속성을 기준으로 정렬하고 싶었습니다.장소마다 다른 정렬이 필요했고 클라이언트가 대화하는 부모 클래스의 공통 기본 정렬이 필요했습니다.필요할 때만 '정렬 키'를 덮어쓰면 됩니다.또한 클래스가 공유할 수 있는 목록으로 저장할 수 있습니다.
그래서 먼저 도우미 방법을 정의했습니다.
def attr_sort(self, attrs=['someAttributeString']:
'''helper to sort by the attributes named by strings of attrs in order'''
return lambda k: [ getattr(k, attr) for attr in attrs ]
그것을 사용하기 위해서
# would defined elsewhere but showing here for consiseness
self.SortListA = ['attrA', 'attrB']
self.SortListB = ['attrC', 'attrA']
records = .... #list of my objects to sort
records.sort(key=self.attr_sort(attrs=self.SortListA))
# perhaps later nearby or in another function
more_records = .... #another list
more_records.sort(key=self.attr_sort(attrs=self.SortListB))
이렇게 하면 생성된 람다 함수를 사용하여 목록을 정렬합니다.object.attrA
그리고 나서.object.attrB
가정하여object
에는 지정된 문자열 이름에 대응하는 getter가 있습니다.그리고 두 번째 사례는 다음과 같이 분류할 수 있습니다.object.attrC
그리고나서object.attrA
.
이것에 의해, 유저나 유닛 테스트에 의해서 동일하게 공유되는 외향 정렬의 선택지가 공개될 가능성이 있습니다.또한 백엔드의 실장과는 결합하지 않고 목록을 제시하기만 하면 됩니다.
목록 목록을 튜플 목록으로 변환한 다음 여러 필드를 기준으로 태플을 정렬합니다.
data=[[12, 'tall', 'blue', 1],[2, 'short', 'red', 9],[4, 'tall', 'blue', 13]]
data=[tuple(x) for x in data]
result = sorted(data, key = lambda x: (x[1], x[2]))
print(result)
출력:
[(2, 'short', 'red', 9), (12, 'tall', 'blue', 1), (4, 'tall', 'blue', 13)]
한 가지 방법이 있습니다. 기본적으로 정렬 함수를 다시 작성하여 정렬 함수의 목록을 가져오고, 각 정렬 함수는 테스트할 속성을 비교합니다. 각 정렬 테스트에서 cmp 함수가 0이 아닌 반환을 반환하는지 확인합니다.람다 리스트의 함수의 람다를 호출하여 호출합니다.
다른 방법처럼 이전 정렬이 아닌 데이터를 단일 통과한다는 것이 장점입니다.또 다른 점은 정렬된 것이 복사를 만드는 것처럼 보이는 반면 정렬된 것은 제자리에 정렬되어 있다는 것입니다.
각 오브젝트가 그룹 내에 있는 클래스 리스트의 순위를 매겨 스코어 기능을 가지는 랭크 함수를 작성하기 위해서 사용하고 있습니다만, 임의의 속성 리스트를 추가할 수 있습니다.람다를 세터라고 부르기 위해 un-lambda와 유사하지만, 람다를 사용하는 것에 주목하십시오.순위 부분은 목록 배열에 사용할 수 없지만, 정렬은 사용할 수 있습니다.
#First, here's a pure list version
my_sortLambdaLst = [lambda x,y:cmp(x[0], y[0]), lambda x,y:cmp(x[1], y[1])]
def multi_attribute_sort(x,y):
r = 0
for l in my_sortLambdaLst:
r = l(x,y)
if r!=0: return r #keep looping till you see a difference
return r
Lst = [(4, 2.0), (4, 0.01), (4, 0.9), (4, 0.999),(4, 0.2), (1, 2.0), (1, 0.01), (1, 0.9), (1, 0.999), (1, 0.2) ]
Lst.sort(lambda x,y:multi_attribute_sort(x,y)) #The Lambda of the Lambda
for rec in Lst: print str(rec)
여기 오브젝트 리스트의 순위를 매기는 방법이 있습니다.
class probe:
def __init__(self, group, score):
self.group = group
self.score = score
self.rank =-1
def set_rank(self, r):
self.rank = r
def __str__(self):
return '\t'.join([str(self.group), str(self.score), str(self.rank)])
def RankLst(inLst, group_lambda= lambda x:x.group, sortLambdaLst = [lambda x,y:cmp(x.group, y.group), lambda x,y:cmp(x.score, y.score)], SetRank_Lambda = lambda x, rank:x.set_rank(rank)):
#Inner function is the only way (I could think of) to pass the sortLambdaLst into a sort function
def multi_attribute_sort(x,y):
r = 0
for l in sortLambdaLst:
r = l(x,y)
if r!=0: return r #keep looping till you see a difference
return r
inLst.sort(lambda x,y:multi_attribute_sort(x,y))
#Now Rank your probes
rank = 0
last_group = group_lambda(inLst[0])
for i in range(len(inLst)):
rec = inLst[i]
group = group_lambda(rec)
if last_group == group:
rank+=1
else:
rank=1
last_group = group
SetRank_Lambda(inLst[i], rank) #This is pure evil!! The lambda purists are gnashing their teeth
Lst = [probe(4, 2.0), probe(4, 0.01), probe(4, 0.9), probe(4, 0.999), probe(4, 0.2), probe(1, 2.0), probe(1, 0.01), probe(1, 0.9), probe(1, 0.999), probe(1, 0.2) ]
RankLst(Lst, group_lambda= lambda x:x.group, sortLambdaLst = [lambda x,y:cmp(x.group, y.group), lambda x,y:cmp(x.score, y.score)], SetRank_Lambda = lambda x, rank:x.set_rank(rank))
print '\t'.join(['group', 'score', 'rank'])
for r in Lst: print r
목록 사이에 연산자 <가 있습니다.예:
[12, 'tall', 'blue', 1] < [4, 'tall', 'blue', 13]
줄 것이다
False
언급URL : https://stackoverflow.com/questions/4233476/sort-a-list-by-multiple-attributes
'programing' 카테고리의 다른 글
JavaScript - 현재 날짜에서 주의 첫 번째 요일을 가져옵니다. (0) | 2022.09.23 |
---|---|
Ubuntu에 mysql gem을 설치하는 데 문제가 있습니다. (0) | 2022.09.23 |
jquery 또는 javascript를 사용하여 객체 배열을 정렬하는 방법 (0) | 2022.09.23 |
문자 목록을 문자열로 변환 (0) | 2022.09.23 |
PHP와 함께 comet을 사용하시겠습니까? (0) | 2022.09.23 |