주어진 인덱스의 요소별로 목록 / 튜플 목록 / 튜플을 정렬하는 방법은 무엇입니까?


658

다음과 같이 목록 목록이나 튜플 목록에 데이터가 있습니다.

data = [[1,2,3], [4,5,6], [7,8,9]]
data = [(1,2,3), (4,5,6), (7,8,9)]

그리고 하위 집합의 두 번째 요소별로 정렬하고 싶습니다. 2,5,8에 의해 정렬 의미 2에서이다 (1,2,3), 5에서이다 (4,5,6). 이 작업을 수행하는 일반적인 방법은 무엇입니까? 튜플 또는 목록을 내 목록에 저장해야합니까?


51
"목록에 튜플이나 목록을 저장해야합니까?"와 관련하여 경험상 가능한 한 불변을 만드는 것이 일반적입니다. 서브리스트를 제자리에서 수정할 필요 가 없으면 튜플로 만드십시오.
Matthew Flaschen

답변:


1114
sorted_by_second = sorted(data, key=lambda tup: tup[1])

또는:

data.sort(key=lambda tup: tup[1])  # sorts in place

10
그것을 더 크게 또는 더 작게 정렬하는 방법을 알고 있습니까?
billwild

63
@billwild : 도움 (정렬). reverse = 참.
Stephen

34
@gethen itemgetter를 사용하는 것이 더 빠르고 간단합니다. key=itemgetter(1)파일이 시작될 때 :from operator import itemgetter
Joschua

3
두 번째 예는 @Cemre입니다. sort여기 List에는 람다 함수를 key매개 변수 로받는 Python 객체의 메서드가 있습니다. 이름을 tup, 또는 t, 또는 원하는대로 지정할 수 있으며 여전히 작동합니다. tup여기에서리스트 튜플의 인덱스를 지정하므로 1, 원래리스트 ( 2, 5, 8) 에서 튜플의 두 번째 값에 의해 정렬이 수행됩니다 .
신경 전달 물질

1
나는 "항목 게터를 사용하는 것이 더 빠르고 간단하다"는 근거없는 주장에 대해 약간 회의적이었다. 나는 직관적 인 생각 주관적 동안 lambda직관적보다 간단 할 방법을 itemgetter클래스 itemgetter 않는 참으로 빠른 것으로 나타납니다 . 왜 이런지 궁금합니다. 필자의 의혹은 lambda모든 로컬 변수를 클로저 컨텍스트로 캡처하는 숨겨진 비용이 발생하지만 itemgetter인스턴스는 그렇지 않다는 것입니다. tl; dr :itemgetter 속도가이기 때문에 항상을 사용하십시오 .
Cecil Curry

236
from operator import itemgetter
data.sort(key=itemgetter(1))

37
이것은 정답입니다. Charlie게시 된 타이밍을 참조 하여 해당 기능 보다 평균 126 % 더 빠르게itemgetter 정렬 하는 클래스를 보여줍니다 . lambda
세실 카레

9
여러 인덱스를 계층 적으로 정렬 할 수도 있습니다.data.sort(key=itemgetter(3,1))
Michael Ohlrogge

57

위의 주석 이외의 다른 방법은 배열을이 행에 추가하는 것입니다.

reverse = True

결과는 다음과 같습니다.

data.sort(key=lambda tup: tup[1], reverse=True)

48

예를 들어 튜플의 두 번째 및 세 번째 요소를 기준으로 여러 기준으로 정렬하려면

data = [(1,2,3),(1,2,1),(1,1,4)]

우선 순위를 설명하는 튜플을 반환하는 람다를 정의하십시오.

sorted(data, key=lambda tup: (tup[1],tup[2]) )
[(1, 1, 4), (1, 2, 1), (1, 2, 3)]

28

Stephen의 대답 은 내가 사용하는 것입니다. 완성도를 높이기 위해 다음과 같은 목록 이해 기능이있는 DSU (장식-정렬-비 장식) 패턴이 있습니다.

decorated = [(tup[1], tup) for tup in data]
decorated.sort()
undecorated = [tup for second, tup in decorated]

또는 더 간결하게 :

[b for a,b in sorted((tup[1], tup) for tup in data)]

Python Sorting HowTo 에서 언급했듯이 , 주요 기능을 사용할 수있게 된 Python 2.4부터는 불필요합니다.


2
따라서이 답변은 Python 2.3-? 좀 더 정교하게 만들 수있는 최신 Python 버전에서 유효한 용도가 있습니까? 그렇지 않다면, 귀찮게하지 않고 ... 그냥 지나가는 것을 보았습니다. 어쨌든, 이것을 기뻐하고 감사합니다.
mechanical_meat

19

튜플의리스트를 정렬하려면 (<word>, <count>)를 들어, count내림차순 및 word알파벳 순서 :

data = [
('betty', 1),
('bought', 1),
('a', 1),
('bit', 1),
('of', 1),
('butter', 2),
('but', 1),
('the', 1),
('was', 1),
('bitter', 1)]

이 방법을 사용합니다.

sorted(data, key=lambda tup:(-tup[1], tup[0]))

결과가 나옵니다.

[('butter', 2),
('a', 1),
('betty', 1),
('bit', 1),
('bitter', 1),
('bought', 1),
('but', 1),
('of', 1),
('the', 1),
('was', 1)]

1
tup [1]이 문자열이면 어떻게됩니까?
eric oc

12

람다없이 :

def sec_elem(s):
    return s[1]

sorted(data, key=sec_elem)

9

itemgetter()보다 약간 빠르지 lambda tup: tup[1]만 증가율은 비교적 작습니다 (약 10-25 %).

(IPython 세션)

>>> from operator import itemgetter
>>> from numpy.random import randint
>>> values = randint(0, 9, 30000).reshape((10000,3))
>>> tpls = [tuple(values[i,:]) for i in range(len(values))]

>>> tpls[:5]    # display sample from list
[(1, 0, 0), 
 (8, 5, 5), 
 (5, 4, 0), 
 (5, 7, 7), 
 (4, 2, 1)]

>>> sorted(tpls[:5], key=itemgetter(1))    # example sort
[(1, 0, 0), 
 (4, 2, 1), 
 (5, 4, 0), 
 (8, 5, 5), 
 (5, 7, 7)]

>>> %timeit sorted(tpls, key=itemgetter(1))
100 loops, best of 3: 4.89 ms per loop

>>> %timeit sorted(tpls, key=lambda tup: tup[1])
100 loops, best of 3: 6.39 ms per loop

>>> %timeit sorted(tpls, key=(itemgetter(1,0)))
100 loops, best of 3: 16.1 ms per loop

>>> %timeit sorted(tpls, key=lambda tup: (tup[1], tup[0]))
100 loops, best of 3: 17.1 ms per loop

여기에서 여러 열에 대한 다양한 역 인수에 대해서는 itemgetter 정렬 솔루션을 참조하십시오. 그런 다음 여러 단계로 정렬을 행으로 정렬해야합니다. stackoverflow.com/questions/14466068/…
Lorenz

6

@Stephen의 대답이 핵심입니다! 더 나은 시각화를위한 예는 다음과 같습니다.

Ready Player One 팬들에게 소리 지르십시오! =)

>>> gunters = [('2044-04-05', 'parzival'), ('2044-04-07', 'aech'), ('2044-04-06', 'art3mis')]
>>> gunters.sort(key=lambda tup: tup[0])
>>> print gunters
[('2044-04-05', 'parzival'), ('2044-04-06', 'art3mis'), ('2044-04-07', 'aech')]

keycompareToJava의 메소드 와 같은 비교를 위해 콜렉션의 항목을 변환하기 위해 호출되는 함수입니다 .

key에 전달 된 매개 변수는 호출 가능한 것이어야합니다. 여기서 사용 lambda하면 익명 함수 (호출 가능)가 작성됩니다.
lambda의 구문은 lambda라는 단어와 반복 가능한 이름, 단일 코드 블록이 뒤 따릅니다.

아래 예에서는 특정 이벤트 및 액터 이름의 정보 abt 시간을 보유하는 튜플 목록을 정렬합니다.

우리는이 목록을 이벤트 발생 시간 (터플의 0 번째 요소)별로 정렬합니다.

참고 s.sort([cmp[, key[, reverse]]]) -s 항목을 제자리에 정렬


-5

튜플을 정렬하는 것은 매우 간단합니다.

tuple(sorted(t))
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.