2017-02-22 1 views
3

python 2.7에서 빈도/발생 수순으로 목록을 정렬하는 방법에 궁금한 점이 있고 2 개의 요소가 동일한 횟수만큼 발생하면 원래 목록의 첫 번째 요소는 새 목록의 다른 요소보다 먼저 나타납니다. 예를 들어python 목록에서 요소를 제거하지 않고 어레 이가 따라 목록을 정렬하는 방법은 무엇입니까?

:

list = [5,6,8,9,8,8,3,4,4,6,6] 
sorted_list = [6,6,6,8,8,8,4,4,5,9,3] 

솔루션 [1,3,3,3,2,2,2,1,1] 국지적 인 출력은 [3 작동하지 않는 이유 어떤 생각, 3,3,2,2,2,1,1,1] 올바른 출력은 [1,1,1,3,3,2,2,2] 입니다. 다시 감사합니다.

+2

난 그냥 대답을 게시하지만 예상 출력에'8'이 왜이'6' 6'가 먼저 발생에도 '불구하고 전에 궁금하네요 원래 목록? – MSeifert

+0

죄송합니다. 원하는 출력을 엉망으로 만들었습니다. 감사합니다. – jonny

+0

MSeifert의 (& my) 코드는'[1,3,3,3,2,2,2,1,1]'에 대한 정답을 제시하고 있습니다. Mureinik의 업데이트 된 버전도 있지만 테스트하지는 않았습니다. –

답변

2

사용할 수 있습니다. Counter 클래스는 정렬 키로 collections입니다.

>>> from collections import Counter 
>>> lst = [5,6,8,9,8,8,3,4,4,6,6] 
>>> c = Counter(lst) 
>>> sorted(lst, key = lambda x : (c[x], x), reverse = True) 
[8, 8, 8, 6, 6, 6, 4, 4, 9, 5, 3] 

가 EDIT : MSeifert는 주석 으로 관계가 파손되어야가 발생 동일한 수의 여러 요소들을 가질 수 있기 때문에 동일한 구성 요소가 함께 그룹화되도록하면 보조 정렬 키로 값 자체를 사용하여 처음 등장한 순서대로 요소의 값이 아닙니다. 이것은 원래 목록에 index 기능을 사용하여 수행 할 수 있습니다 :

>>> sorted(lst, key = lambda x : (-1 * c[x], lst.index(x))) 
[6, 6, 6, 8, 8, 8, 4, 4, 5, 9, 3] 
+0

2 차 정렬 키는 항상 내 마음에 특별한 자리를 가지고 있습니다. –

+0

나는'c '를 정의하는 걸 잊었을 것 같아요. –

+0

@ Jean-FrançoisFabre yup - 두 번 시도해 보았습니다. 관련 선. 분명히, 나는 잊었다 :-) 알아 차 렸던 것에 대해 편집되고 고쳤다! – Mureinik

2

는 당신이 첫 번째 인덱스 및 각 항목의 수를 찾을 필요가 정렬 이런 종류의 작업을 수행하려면. 나는 둘 다 할 하나 개의 기능을 사용합니다하지만 다른 방법도 있습니다 : 그것은 당신에게 반전 정렬합니다 때문에

>>> lst = [5,6,8,9,8,8,3,4,4,6,6] 

>>> counts, firstidx = count_and_first_index(lst) 

>>> sorted(lst, key=lambda x: (counts[x], -firstidx[x]), reverse=True) 
[6, 6, 6, 8, 8, 8, 4, 4, 5, 9, 3] 

나는 index을 부정 :

def count_and_first_index(it): 
    dct_counts = {} 
    dct_first = {} 
    for idx, item in enumerate(it): 
     if item in dct_counts: 
      dct_counts[item] += 1 
     else: 
      dct_counts[item] = 1 
      dct_first[item] = idx 

    return dct_counts, dct_first 

그런 다음 정렬

key -argument를 사용하여 간단는 첫 번째 항목을 먼저 원했습니다. 그러나 당신은 또한 counts을 부정하고 reverse 제거 할 수 있습니다 :

>>> sorted(lst, key=lambda x: (-counts[x], firstidx[x])) 
[6, 6, 6, 8, 8, 8, 4, 4, 5, 9, 3] 
+1

나는 계산과 인덱싱을하는 방식이 다소 비효율적이긴하지만 정렬 된 (lst, key = lambda x : (- lst.count (x), lst.index (x))) (O (n) 대신에 O (n^2)). –

+0

@ PM2Ring 네, 그렇기 때문에 "둘 다 할 수있는 한 가지 기능을 사용 하겠지만 다른 접근 방식도 있습니다."라고 썼습니다. O (n ** 2) 접근법을 사용하는 것을 망칠 것 같았습니다. ('count'와'index'는 분리 된 연산이기 때문에리스트를 두 번 통과합니다!)'O (n)'접근법이 짧고) 가능합니다. – MSeifert

+0

음, 2O (n²)는 여전히 O (n²)입니다. –

관련 문제