목록 목록이 있습니다.
[[12, 'tall', 'blue', 1],
[2, 'short', 'red', 9],
[4, 'tall', 'blue', 13]]
하나의 요소를 기준으로 정렬하려면 키가 큰 요소를 말하면을 통해 할 수 있습니다 s = sorted(s, key = itemgetter(1))
.
나는별로 정렬하고 싶었다면 모두 키 / 짧고 색상, 나는 각 요소에 대해 한 번, 일종의 두 번 할 수 있지만 빠른 방법은 무엇입니까?
답변
키는 튜플을 반환하는 함수일 수 있습니다.
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))
답변
이것이 가장 파이썬적인 방법인지 확실하지 않습니다 … 정수 값을 내림차순으로 정렬하고 알파벳 순서로 2를 정렬 해야하는 튜플 목록이 있습니다. 이것은 알파벳 정렬이 아닌 정수 정렬을 취소해야했습니다. 내 해결책은 다음과 같습니다. (시험 btw에서 즉시 정렬 된 기능을 ‘중첩’할 수 있다는 것을 알지 못했습니다)
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)]
답변
당신이 사용할 수있는 것 같습니다 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
한 다음 제공된 문자열 이름에 해당하는 getter가 object.attrB
있다고 가정 object
합니다. 그리고 두 번째의 경우는 기준으로 정렬 할 object.attrC
다음object.attrA
.
또한 소비자, 단위 테스트에서 공유 할 외부 정렬 선택 항목을 노출하거나 잠재적으로 사용자가 api의 일부 작업에 대해 정렬 방법을 알려줄 수 있습니다. 백엔드 구현에 연결
답변
몇 년 동안 파티에 늦었지만 두 가지 기준으로 정렬 하고 사용 하고 싶습니다 reverse=True
. 다른 사람이 방법을 알고 싶어하는 경우 기준 (기능)을 괄호로 묶을 수 있습니다.
s = sorted(my_list, key=lambda i: ( criteria_1(i), criteria_2(i) ), reverse=True)
답변
한 가지 방법은 다음과 같습니다. 기본적으로 정렬 함수 목록을 가져 오기 위해 정렬 함수를 다시 작성합니다. 각 정렬 함수는 테스트하려는 속성을 비교하고 각 정렬 테스트에서 cmp 함수가 0이 아닌 리턴을 리턴하는지 확인합니다. 그렇다면 중단하고 반환 값을 보내십시오. Lambda 목록의 함수 중 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
답변
