python . 단어의 빈도수대로 정렬하고, 빈도수가 같다면 단어의 알파벳순으로 정렬해서 출력하는 법을 알고 싶습니다.

조회수 9295회

start law year time joy time word family friend year tonight year law time joy work library word justice start time work president year start time president country joy family

이걸 입력으로 주면 (빈도수, 단어) 를 요소로

[(2, 'work'), (2, 'word'), (2, 'family'), (1, 'justice'), (3, 'joy'), (4, 'year'), (1, 'library'), (1, 'country'), (1, 'tonight'), (3, 'start'), (5, 'time'), (2, 'president'), (2, 'law'), (1, 'friend')]

이런 리스트를 만들 수 있는데요,

어떻게하면 빈도수로 정렬하고 work와 word처럼 빈도수가 같을 때 알파벳순으로 정렬하라는 옵션을 줄 수 있을까요?

Input이 start law year time joy time word family friend year tonight year law time joy work library word justice start time work president year start time president country joy family 면

Output이 time year joy start family law president word work country friend justice library tonight 이 나와야 해요

3 답변

  • 좋아요

    0

    싫어요
    채택 취소하기

    아래에 '실행하기'를 눌러보세요.

    words = ["start","law","year","time","joy","time","word","family","friend","year","tonight","year","law","time","joy","work","library","word","justice","start","time","work","president","year","start","time","president","country","joy","family"]
    words_count={}
    for word in words:
        if word in words_count:
            words_count[word] += 1
        else:
            words_count[word] = 1
    sorted_words = sorted([(k,v) for k,v in words_count.items()], key=lambda word_count: -word_count[1])
    print([w[0] for w in sorted_words])
    

    알파벳으로 정렬까지 넣고 싶으시면 comparator를 이용하시면 됩니다.

    import functools
    
    def comparator(x, y):
        return x[0]*x[1]-y[0]*y[1]
    
    
    l = [[-50,5], [2,2], [1,2], [9,3]]
    print(sorted(l, key=functools.cmp_to_key(comparator)))
    
    • 실행해보시면 알겠지만, 똑같이 3번나온 start와 joy중에서 start가 먼저나오게 됩니다. 알파벳 순으로 하라고 했으니 joy가 먼저 나와야 하는데 말이죠. 이게 어려운 부분입니다 ㅠㅠ 임정섭 2017.1.3 12:51
    • 알파벳 정렬까지 원하시면 lambda 대신 comparator 함수를 만들어 쓰시면 되겠습니다. 답변을 업데이트 해 두었습니다. 너무 다 해 드리면 재미 없는것 같아서 여기까지만... 정토드 2017.1.3 14:12
    • 옙, 도전해보겠습니다. 답변 감사드립니다 임정섭 2017.1.3 21:35
  • 아래와 같이 sorted 를 두번하는 방법도 있습니다.

    from collections import Counter
    
    s = "start law year time joy time word family friend year tonight year law time joy work library word justice start time work president year start time president country joy family"
    
    sorted(sorted(Counter(s.split()).most_common(), key=lambda pair:pair[0], reverse=False), key=lambda pair:pair[1], reverse=True)
    Out[59]: 
    [('time', 5),
     ('year', 4),
     ('joy', 3),
     ('start', 3),
     ('family', 2),
     ('law', 2),
     ('president', 2),
     ('word', 2),
     ('work', 2),
     ('country', 1),
     ('friend', 1),
     ('justice', 1),
     ('library', 1),
     ('tonight', 1)]
    
    • 답변 감사합니다! 아주 간단하네요 임정섭 2017.2.10 11:44
    • 그런데, 이해가 되질 않습니다. sorted를 두번 하면 처음의 sort는 의미가 없어지는 게 아닌가요? 임정섭 2017.2.10 14:53
    • comparator 를 만들어 보셨으면 이해하는데 도움이 될 수 있습니다. 핵심은 같은 순위의 항목일 경우 비교순서순이라는 겁니다. 즉 첫번째 sorted에서 알파벳 정렬을 해서 같은 순위일 때 알파벳 순서로 먼저 정렬을 합니다 그 후 다시 빈도수로 정렬을 하게 되면 같은 빈도수인경우 알파벳순서가 유지되게 됩니다. 정영훈 2017.2.10 20:34
  • linq 처럼 사용할 수 있는 asq(https://github.com/sixty-north/asq) 모듈도 쓸만합니다.

    from collections import Counter
    from asq.initiators import query
    
    s = "start law year time joy time word family friend year tonight year law time joy work library word justice start time work president year start time president country joy family"
    
    query(Counter(s.split()).most_common()).order_by_descending(lambda pair:pair[1]).then_by(lambda pair:pair[0]).to_list()
    Out: 
    [('time', 5),
     ('year', 4),
     ('joy', 3),
     ('start', 3),
     ('family', 2),
     ('law', 2),
     ('president', 2),
     ('word', 2),
     ('work', 2),
     ('country', 1),
     ('friend', 1),
     ('justice', 1),
     ('library', 1),
     ('tonight', 1)]
    

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)