정렬 된 CSV로 만든 다음 목록이 있습니다.
list1 = sorted(csv1, key=operator.itemgetter(1))
실제로 목록을 두 가지 기준으로 정렬하고 싶습니다. 먼저 필드 1의 값을 기준으로 한 다음 필드 2의 값을 기준으로 정렬합니다. 어떻게해야합니까?
__lt__()
클래스에서 메소드 정의 또는 일부 클래스에서 상속"입니다 . 그것은 훨씬 더 나은 정식으로 만들 것입니다.
정렬 된 CSV로 만든 다음 목록이 있습니다.
list1 = sorted(csv1, key=operator.itemgetter(1))
실제로 목록을 두 가지 기준으로 정렬하고 싶습니다. 먼저 필드 1의 값을 기준으로 한 다음 필드 2의 값을 기준으로 정렬합니다. 어떻게해야합니까?
__lt__()
클래스에서 메소드 정의 또는 일부 클래스에서 상속"입니다 . 그것은 훨씬 더 나은 정식으로 만들 것입니다.
답변:
이처럼 :
import operator
list1 = sorted(csv1, key=operator.itemgetter(1, 2))
operator
가져와야하는 모듈입니다.
람다 함수를 사용할 때 아무 것도 가져올 필요가 없습니다.
다음 list
은 첫 번째 요소를 기준으로 정렬 한 다음 두 번째 요소를 기준으로 정렬 합니다.
sorted(list, key=lambda x: (x[0], -x[1]))
-
에서 -x[1]
독립을 위해?
파이썬은 안정적인 정렬을 가지고 있으므로 성능이 문제가되지 않는 가장 간단한 방법은 필드 2로 정렬 한 다음 필드 1로 다시 정렬하는 것입니다.
그것은 당신에게 당신이 원하는 결과를 줄 것입니다, 유일한 캐치는 그것이 큰 목록이라면 (또는 당신이 그것을 자주 정렬하고 싶다면) sort를 두 번 호출하는 것은 용납 할 수없는 오버 헤드 일 수 있다는 것입니다.
list1 = sorted(csv1, key=operator.itemgetter(2))
list1 = sorted(list1, key=operator.itemgetter(1))
이 방법을 사용하면 일부 열의 역 정렬을 원하는 상황을 쉽게 처리 할 수 있으며 필요한 경우 'reverse = True'매개 변수 만 포함하면됩니다.
그렇지 않으면 여러 매개 변수를 itemgetter에 전달하거나 수동으로 튜플을 빌드 할 수 있습니다. 아마 더 빠를 지 모르지만 일부 열이 역 정렬되기를 원한다면 잘 일반화되지 않는다는 문제가 있습니다 (숫자 열은 무시하여 정렬 할 수는 있지만 정렬이 안정적이지 않습니다).
따라서 역 정렬 된 열이 필요하지 않으면 여러 인수를 itemgetter로 이동하십시오. 가능한 경우 열이 숫자가 아니거나 여러 연속 정렬을 위해 정렬을 안정적으로 유지하려고합니다.
편집 : 이것이 원래의 질문에 어떻게 대답하는지 이해하는 데 어려움을 겪는 주석가의 경우, 정렬의 안정적인 특성으로 각 키에 대해 개별 정렬을 수행하고 여러 기준으로 정렬 된 데이터로 끝내는 방법을 정확하게 보여주는 예가 있습니다.
DATA = [
('Jones', 'Jane', 58),
('Smith', 'Anne', 30),
('Jones', 'Fred', 30),
('Smith', 'John', 60),
('Smith', 'Fred', 30),
('Jones', 'Anne', 30),
('Smith', 'Jane', 58),
('Smith', 'Twin2', 3),
('Jones', 'John', 60),
('Smith', 'Twin1', 3),
('Jones', 'Twin1', 3),
('Jones', 'Twin2', 3)
]
# Sort by Surname, Age DESCENDING, Firstname
print("Initial data in random order")
for d in DATA:
print("{:10s} {:10s} {}".format(*d))
print('''
First we sort by first name, after this pass all
Twin1 come before Twin2 and Anne comes before Fred''')
DATA.sort(key=lambda row: row[1])
for d in DATA:
print("{:10s} {:10s} {}".format(*d))
print('''
Second pass: sort by age in descending order.
Note that after this pass rows are sorted by age but
Twin1/Twin2 and Anne/Fred pairs are still in correct
firstname order.''')
DATA.sort(key=lambda row: row[2], reverse=True)
for d in DATA:
print("{:10s} {:10s} {}".format(*d))
print('''
Final pass sorts the Jones from the Smiths.
Within each family members are sorted by age but equal
age members are sorted by first name.
''')
DATA.sort(key=lambda row: row[0])
for d in DATA:
print("{:10s} {:10s} {}".format(*d))
이것은 실행 가능한 예제이지만 실행하는 사람들을 저장하기 위해 출력은 다음과 같습니다.
Initial data in random order
Jones Jane 58
Smith Anne 30
Jones Fred 30
Smith John 60
Smith Fred 30
Jones Anne 30
Smith Jane 58
Smith Twin2 3
Jones John 60
Smith Twin1 3
Jones Twin1 3
Jones Twin2 3
First we sort by first name, after this pass all
Twin1 come before Twin2 and Anne comes before Fred
Smith Anne 30
Jones Anne 30
Jones Fred 30
Smith Fred 30
Jones Jane 58
Smith Jane 58
Smith John 60
Jones John 60
Smith Twin1 3
Jones Twin1 3
Smith Twin2 3
Jones Twin2 3
Second pass: sort by age in descending order.
Note that after this pass rows are sorted by age but
Twin1/Twin2 and Anne/Fred pairs are still in correct
firstname order.
Smith John 60
Jones John 60
Jones Jane 58
Smith Jane 58
Smith Anne 30
Jones Anne 30
Jones Fred 30
Smith Fred 30
Smith Twin1 3
Jones Twin1 3
Smith Twin2 3
Jones Twin2 3
Final pass sorts the Jones from the Smiths.
Within each family members are sorted by age but equal
age members are sorted by first name.
Jones John 60
Jones Jane 58
Jones Anne 30
Jones Fred 30
Jones Twin1 3
Jones Twin2 3
Smith John 60
Smith Jane 58
Smith Anne 30
Smith Fred 30
Smith Twin1 3
Smith Twin2 3
특히 두 번째 단계에서 reverse=True
매개 변수가 어떻게 이름을 순서대로 유지 하는가에 따라 목록을 정렬 한 후 뒤집 으면 세 번째 정렬 키에 대해 원하는 순서를 잃게됩니다.
list1 = sorted(csv1, key=lambda x: (x[1], x[2]) )
tuple()
(당신이 계산하는 경우, 또는 오히려, 세 개의 인수를받을 수 있습니다 self
)
return
진술은 return tuple((x[1], x[2]))
또는 간단 해야합니다 return x[1], x[2]
. 다른 방향으로 정렬하려면 아래 @jaap 답변을 참조하십시오.
tuple(x[1:3])
어떤 이유로 튜플 표시 목록 대신 튜플 생성자를 사용하려는 경우 x[1], x[2]
. 또는 keyfunc = operator.itemgetter(1, 2)
함수를 직접 작성하지 마십시오.
employees.sort(key = lambda x:x[1])
employees.sort(key = lambda x:x[0])
파이썬 정렬이 제자리에 있고 안정적이기 때문에 .sort를 lambda와 함께 2 번 사용할 수도 있습니다. 먼저 두 번째 요소 x [1]에 따라 목록을 정렬합니다. 그런 다음 첫 번째 요소 x [0] (가장 높은 우선 순위)을 정렬합니다.
employees[0] = Employee's Name
employees[1] = Employee's Salary
이것은 다음을 수행하는 것과 같습니다. employee.sort (key = lambda x : (x [0], x [1]))