2013-01-04 1 views
1

좋은 제목으로 나오지 못해 죄송합니다.파이썬의 단일 요소에서 다른 우선 순위의 중첩 목록을 정렬하는 방법은 무엇입니까?

나는 목록을 가지고 : X가 난 상관 없어 뭔가

some_list = [[X, '4x01'], [X, '3x02'], [X, '4x02'], [X, '3x01']] 

.

  1. 내림차순으로 첫 번째 문자 :

    나는 다음과 같은 우선 순위 목록의 두 번째 요소를 정렬합니다.

  2. 오름차순으로 마지막 2 문자.

최종 출력은 다음과 같아야합니다

some_list = [[X, '4x01'], [X, '4x02'], [X, '3x01'], [X, '3x02']] 

: 잘못된 답을 제공하는 솔루션입니다 :

output = sorted(some_list, key=lambda lis: lis[3], reverse=True) 

답변

1

이 경우 @Amber와 같은 복합 키를 사용할 수 있습니다. 그러나이 방법이 항상 작동하는 것은 아닙니다. 예를 들어 두 구성 요소가 모두 2자인 경우 (예 : -ord(x[1][0]) 트릭이 더 이상 작동하지 않을 수 있기 때문에) 실패합니다. 여기

는보다 일반적인 솔루션입니다 :

In [15]: X = None 

In [16]: some_list = [[X, '4x01'], [X, '3x02'], [X, '4x02'], [X, '3x01']] 

In [17]: l = sorted(some_list, key=lambda (x,y):y[-2:]) 

In [18]: l = sorted(l, key=lambda (x,y):y[:1], reverse=True) 

In [19]: l 
Out[19]: [[None, '4x01'], [None, '4x02'], [None, '3x01'], [None, '3x02']] 

그것은 한 번에 목록 하나 개의 기준을 정렬하고, 파이썬의 종류가 stable 사실을 사용한다. 다음

def f((x1,y1), (x2,y2)): 
    c = cmp(y1[:1], y2[:1]) 
    if c != 0: return -c 
    return cmp(y1[-2:], y2[-2:]) 

이 사용할 수있다 :이

In [39]: sorted(some_list, cmp=f) 
Out[39]: [[None, '4x01'], [None, '4x02'], [None, '3x01'], [None, '3x02']] 
+0

이 지점에 도달하면 더 나은 옵션은 아마 그냥 비교 함수를 작성하는 것일 것입니다. 그렇게하면 목록을 두 번 정렬하지 않아도됩니다 (목록이 클 경우 잠재적으로 값 비싼 작업 임). – Amber

+0

@Amber : 공정한 포인트. 그래도이 방법은 알만한 가치가있는 유용한 기술입니다. – NPE

+0

당신의 주장을 이해시켜 주시길 바랍니다. 2 자 길이라면'-ord (x [1] [: 1])'이 대신 속임수를 쓰지 않겠습니까? – elwc

5
output = sorted(some_list, key=lambda x: (-ord(x[1][0]), x[1][-2:])) 

예 실행 (정의 X None로 단지 그래서 목록 정의를 복사하여 붙여 넣을 수 있습니다 :

>>> X = None 
>>> some_list = [[X, '4x01'], [X, '3x02'], [X, '4x02'], [X, '3x01']] 
>>> output = sorted(some_list, key=lambda x: (-ord(x[1][0]), x[1][-2:])) 
>>> output 
[[None, '4x01'], [None, '4x02'], [None, '3x01'], [None, '3x02']] 
+0

이 바로 표시에

이보다 더 일반적인 접근법은 비교기를 제공하는 것이다. 나는 수 시간의 생각에도 불구하고이 대답에 결코 도달하지 않을 것이다. 감사합니다. – elwc

+0

파이썬 원 - 라이너가 아주 좋습니다. Perl과 달리 많은 것을 할 수 있습니다. 여전히 읽을 수 있습니다. –