python 파이썬 어떻게 값순으로 사전을 정렬합니까?




파이썬 튜플 (24)

값으로 영구적으로 정렬되는 사전 인 skip dict 를 사용할 수 있습니다.

>>> data = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
>>> SkipDict(data)
{0: 0.0, 2: 1.0, 1: 2.0, 4: 3.0, 3: 4.0}

keys() , values() 또는 items() 를 사용하면 값순 정렬 순서로 반복합니다.

이것은 스킵리스트 데이터 구조를 사용하여 구현됩니다.

문자열 필드와 숫자 필드 : 데이터베이스의 두 필드에서 읽은 값의 사전 있습니다. 문자열 필드는 고유하므로 사전의 키입니다.

키를 정렬 할 수는 있지만 값을 기준으로 정렬 할 수 있습니까?

참고 : 스택 오버플로 질문을 읽었습니다. 사전 목록을 Python으로 정렬하려면 어떻게합니까? 아마도 사전 목록을 갖기 위해 내 코드를 변경할 수는 있지만 사전 목록이 필요 없기 때문에 간단한 해결책이 있는지 알고 싶었습니다.


사전에서 가장 높은 값에서 가장 낮은 값 순으로 정렬 된 키 - 값 쌍의 목록을 반환합니다.

sorted(d.items(), key=lambda x: x[1], reverse=True)

키별로 정렬 된 사전의 경우 다음을 사용하십시오.

sorted(d.items(), reverse=True)

사전 자체는 정렬 할 수 없기 때문에 반환은 튜플 목록입니다.

이것은 인쇄되거나 추가 계산으로 보내질 수 있습니다.


값이 숫자 인 경우 컬렉션에서 카운터를 사용할 수도 있습니다.

from collections import Counter

x={'hello':1,'python':5, 'world':3}
c=Counter(x)
print c.most_common()


>> [('python', 5), ('world', 3), ('hello', 1)]    

다음 접근법을 시도하십시오. 다음 데이터로 mydict라는 사전을 정의하겠습니다.

mydict = {'carl':40,
          'alan':2,
          'bob':1,
          'danny':3}

사전을 키별로 정렬하려면 다음과 같이 할 수 있습니다.

for key in sorted(mydict.iterkeys()):
    print "%s: %s" % (key, mydict[key])

그러면 다음과 같은 결과가 반환됩니다.

alan: 2
bob: 1
carl: 40
danny: 3

다른 한편으로, 만약 질문에서와 같이 값으로 사전을 정렬하고 싶다면, 다음을 할 수 있습니다 :

for key, value in sorted(mydict.iteritems(), key=lambda (k,v): (v,k)):
    print "%s: %s" % (key, value)

이 명령의 결과 (사전을 값으로 정렬)는 다음을 리턴해야합니다.

bob: 1
alan: 2
danny: 3
carl: 40

전문적으로 사전은 시퀀스가 ​​아니므로 사전을 정렬 할 수 없습니다. 너는 뭔가를 할 수있다.

sorted(a_dictionary.values())

성능이 큰 문제는 아니라고 가정합니다.


최근 Python 2.7에는 항목이 추가 된 순서를 기억하는 새로운 OrderedDict 유형이 있습니다.

>>> d = {"third": 3, "first": 1, "fourth": 4, "second": 2}

>>> for k, v in d.items():
...     print "%s: %s" % (k, v)
...
second: 2
fourth: 4
third: 3
first: 1

>>> d
{'second': 2, 'fourth': 4, 'third': 3, 'first': 1}

원본에서 새 주문한 사전을 만들려면 값별로 정렬하십시오.

>>> from collections import OrderedDict
>>> d_sorted_by_value = OrderedDict(sorted(d.items(), key=lambda x: x[1]))

OrderedDict는 정상적인 dict처럼 작동합니다.

>>> for k, v in d_sorted_by_value.items():
...     print "%s: %s" % (k, v)
...
first: 1
second: 2
third: 3
fourth: 4

>>> d_sorted_by_value
OrderedDict([('first': 1), ('second': 2), ('third': 3), ('fourth': 4)])

파이썬 2.7에서 간단히 :

from collections import OrderedDict
# regular unsorted dictionary
d = {'banana': 3, 'apple':4, 'pear': 1, 'orange': 2}

# dictionary sorted by key
OrderedDict(sorted(d.items(), key=lambda t: t[0]))
OrderedDict([('apple', 4), ('banana', 3), ('orange', 2), ('pear', 1)])

# dictionary sorted by value
OrderedDict(sorted(d.items(), key=lambda t: t[1]))
OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('apple', 4)])

복사 붙여 넣기 : http://docs.python.org/dev/library/collections.html#ordereddict-examples-and-recipes

즐겨 ;-)


당신은 collections.Counter 를 사용할 수 있습니다. 숫자 및 비 숫자 값 모두에 대해 작동합니다.

>>> x = {1: 2, 3: 4, 4:3, 2:1, 0:0}
>>> from collections import Counter
>>> #To sort in reverse order
>>> Counter(x).most_common()
[(3, 4), (4, 3), (1, 2), (2, 1), (0, 0)]
>>> #To sort in ascending order
>>> Counter(x).most_common()[::-1]
[(0, 0), (2, 1), (1, 2), (4, 3), (3, 4)]
>>> #To get a dictionary sorted by values
>>> from collections import OrderedDict
>>> OrderedDict(Counter(x).most_common()[::-1])
OrderedDict([(0, 0), (2, 1), (1, 2), (4, 3), (3, 4)])

키에 전달할 수있는 사용자 정의 함수를 사용할 수도 있습니다.

def dict_val(x):
    return x[1]
x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
sorted_x = sorted(x.items(), key=dict_val)

한 가지 방법은 labmda 함수를 사용하는 것입니다.

x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
sorted_x = sorted(x.items(), key=lambda t: t[1])

파이썬 3.6 부터 빌트인 dict이 주문 될 것이다.

다행히 OP의 독창적 인 사용 사례는 고유 한 문자열 ID를 가진 데이터베이스에서 가져온 쌍을 키와 숫자 값으로 사용하여 내장 된 Python v3.6 + dict에 삽입 순서를 준수해야합니다.

다음과 같은 데이터베이스 쿼리에서 결과로 나타나는 두 개의 열 테이블 식을 말하면 :

SELECT a_key, a_value FROM a_table ORDER BY a_value;

두 개의 파이썬 튜플 인 k_seq와 v_seq (숫자 인덱스로 정렬되고 길이가 같은)에 저장됩니다.

k_seq = ('foo', 'bar', 'baz')
v_seq = (0, 1, 42)
ordered_map = dict(zip(k_seq, v_seq))

나중에 출력 허용 :

for k, v in ordered_map.items():
    print(k, v)

이 경우에 항복한다 (새로운 Python 3.6+ built-in dict!) :

foo 0
bar 1
baz 42

v의 가치와 동일한 순서로

내 컴퓨터에 Python 3.5를 설치하면 현재 다음과 같은 결과가 나타납니다.

bar 1
foo 0
baz 42

세부:

레이몬드 헤 팅거 (Raymond Hettinger)에 의해 제안 된 바와 같이 ( "더 빠른 반복을 가진 더 컴팩트 한 사전"이라는 주제로 python-dev에 메일 보내기) 빅터 스티너의 메일에서 발표 된 "Python 3.6 dict"라는 python-dev 는 압축하고 개인용 버전을 얻고 키워드가 정렬됩니다. " 문제 27350 "Compact and ordered dict " 수정 / 구현으로 인서트 순서를 유지하기 위해 내장 된 dict를 사용할 수있게되었습니다!

잘하면이 첫 단계로 얇은 레이어 OrderedDict 구현으로 이어질 것입니다. @ JimFasarakis-Hilliard가 지적했듯이 일부에서는 앞으로 OrderedDict 유형에 대한 사용 사례를 볼 수 있습니다. 파이썬 커뮤니티가 시간의 시험에 부합 할 것인지, 다음 단계가 될 것인지를 면밀히 검토 할 것입니다.

안정적인 주문으로 열린 가능성을 놓치지 않도록 코딩 습관을 다시 생각해 볼 시간.

  • 키워드 인수 및
  • (중간) dict 저장소

첫 번째는 함수 및 메서드 구현시 디스패치를 ​​완화하는 경우가 있기 때문입니다.

두 번째는 파이프 라인을 처리 할 때 중간 저장소로 사용하는 것이 더 쉽습니다.

Raymond Hettinger는 San Francisco Python Meetup Group 프리젠 테이션 2016-DEC-08에서 " The Tech Behind Python 3.6 Dictionaries "라는 문서를 친절하게 제공했습니다.

그리고 아마도 꽤 많은 질문 및 답변 페이지에는이 정보의 변종이 제공 될 것이며 많은 고품질 응답에는 버전 별 업데이트가 필요합니다.

경고 Emptor (아래 업데이트 2017-12-15 참조) :

@ajcr은 "이 새로운 구현의 주문 보존 측면은 구현 세부 사항으로 간주되므로 신뢰할 수 없습니다." ( whatsnew36에서 ) nit picking은 아니지만 , 인용문은 약간 비관적으로 잘라졌다 ;-). "(앞으로는 변경 될 수 있지만, 현재와 미래의 모든 Python 구현에 대한 주문 보존 의미를 지정하기 위해 언어 사양을 변경하기 전에 몇 가지 릴리스의 언어로이 새로운 사전 구현을 사용하는 것이 바람직합니다. 임의의 반복 명령이 여전히 유효한 이전 버전의 언어 (예 : Python 3.5)와의 하위 호환성을 유지하는 데 도움이됩니다. "

따라서 일부 인간 언어 (예 : 독일어)에서와 같이 사용법이 언어를 형성하고 이제는 의지가 ... whatsnew36 에서 선언되었습니다.

업데이트 2017-12-15 :

python-dev리스트에 메일을 보낸 Guido van Rossum은 다음과 같이 선언했다.

그렇게 만들어. "Dict 삽입 주문 유지"판결입니다. 감사!

따라서, dict 삽입 순서의 버전 3.6 CPython 부작용이 이제는 언어 사양의 일부가되었습니다 (더 이상 구현 세부 사항이 아닙니다). 이 메일 스레드는 또한 collections.OrderedDict 때 눈에 띄는 디자인 목표를 나타 냈습니다. 토론 중에 Raymond Hettinger가 상기 한대로.


파이썬의 정렬 된 함수를 사용할 수 있습니다.

sorted(iterable[, cmp[, key[, reverse]]])

따라서 다음을 사용할 수 있습니다.

sorted(dictionary.items(),key = lambda x :x[1])

정렬 된 기능에 대한 자세한 내용은 다음 링크를 참조하십시오. https://docs.python.org/2/library/functions.html#sorted


Dicts는 정렬 될 수 없지만, Dicts에서 정렬 된 목록을 작성할 수 있습니다.

dict 값의 정렬 된 목록 :

sorted(d.values())

값으로 정렬 된 (키, 값) 쌍의 목록입니다.

from operator import itemgetter
sorted(d.items(), key=itemgetter(1))

나는 같은 문제를 겪었고, 나는 이것을 다음과 같이 풀었다.

WantedOutput = sorted(MyDict, key=lambda x : MyDict[x]) 

( "딕트를 분류 할 수 없다"라고 답한 사람들은 그 질문을 읽지 못했습니다! 사실, "나는 키를 정렬 할 수 있지만 어떻게 값을 기준으로 정렬 할 수 있습니까?"라는 명확한 의미는 키는 값의 값에 따라 정렬됩니다.)

순서가 잘 정의되어 있지 않음을주의하십시오 (동일한 값을 갖는 키는 출력 목록에서 임의의 순서로 나타납니다).


다음은 d.values()d.keys() 에서 zip을 사용하는 솔루션입니다. 사전보기 객체의이 링크 아래 몇 줄은 다음과 같습니다.

이렇게하면 zip () : pairs = zip (d.values ​​(), d.keys ())를 사용하여 (값, 키) 쌍을 만들 수 있습니다.

그래서 우리는 다음을 할 수 있습니다 :

d = {'key1': 874.7, 'key2': 5, 'key3': 8.1}

d_sorted = sorted(zip(d.values(), d.keys()))

print d_sorted 
# prints: [(5, 'key2'), (8.1, 'key3'), (874.7, 'key1')]

사전을 정렬 할 수 없으며 정렬 된 사전의 표현을 가져올 수 없습니다. 사전은 본질적으로 순서가 없지만 목록이나 튜플과 같은 다른 유형은 그렇지 않습니다. 정렬 된 값을 나타 내기 위해 정렬 된 데이터 유형이 필요합니다. 목록은 아마도 튜플 목록 일 것입니다.

예를 들어,

import operator
x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
sorted_x = sorted(x.items(), key=operator.itemgetter(1))

sorted_x 는 각 튜플의 두 번째 요소로 정렬 된 튜플 목록입니다. dict(sorted_x) == x .

값 대신 키를 정렬하려는 경우

import operator
x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
sorted_x = sorted(x.items(), key=operator.itemgetter(0))

파이썬 3에서는 언 패킹이 허용되지 않기 때문에 [1] 우리는

x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
sorted_by_value = sorted(x.items(), key=lambda kv: kv[1])

주어진 사전

e = {1:39, 4:34, 7:110, 2:87}

정렬

sred = sorted(e.items(), key=lambda value: value[1])

결과

[(4, 34), (1, 39), (2, 87), (7, 110)]

람다 함수를 사용하여 값으로 항목을 정렬하고 변수 내에서 처리 할 수 ​​있습니다.이 경우 sred 는 원본 사전을 사용합니다.

희망이 도움이됩니다!


행크 게이의 대답과 거의 같습니다.

    sorted([(value,key) for (key,value) in mydict.items()])

또는 John Fouhy가 제안한대로 비트를 최적화했습니다.

    sorted((value,key) for (key,value) in mydict.items())


Dilettant가 지적한 것처럼 , Python 3.6은 이제 순서를 유지할 것입니다! 나는 iterable (tuple, list, dict)의 정렬을 용이하게하는 함수를 공유 할 것이라고 생각했다. 후자의 경우 키 또는 값 중 하나를 정렬 할 수 있으며 숫자 비교를 고려할 수 있습니다. 3.6 이상인 경우에만!

sorted ()뿐만 아니라 문자열을 포함하는 iterable에서 sorted를 사용하려고하면 sorted ()가 실패합니다. 물론 문자열 비교를 str ()과 강제로 수행 할 수 있습니다. 그러나 어떤 경우에는 1220 보다 작은 실제 수치 비교를 원합니다 (문자열 비교에서는 그렇지 않습니다). 그래서 나는 다음을 생각해 냈습니다. 명시 적 숫자 비교를 num_as_num 플래그를 사용하면 모든 값을 num_as_num 로 변환하여 명시 적 숫자 정렬을 시도합니다. 성공하면 숫자 정렬을 수행하고 그렇지 않으면 문자열 비교를 사용합니다.

개선 또는 푸시 요청에 대한 의견 환영.

def sort_iterable(iterable, sort_on=None, reverse=False, num_as_num=False):
    def _sort(i):
      # sort by 0 = keys, 1 values, None for lists and tuples
      try:
        if num_as_num:
          if i is None:
            _sorted = sorted(iterable, key=lambda v: float(v), reverse=reverse)
          else:
            _sorted = dict(sorted(iterable.items(), key=lambda v: float(v[i]), reverse=reverse))
        else:
          raise TypeError
      except (TypeError, ValueError):
        if i is None:
          _sorted = sorted(iterable, key=lambda v: str(v), reverse=reverse)
        else:
          _sorted = dict(sorted(iterable.items(), key=lambda v: str(v[i]), reverse=reverse))

      return _sorted

    if isinstance(iterable, list):
      sorted_list = _sort(None)
      return sorted_list
    elif isinstance(iterable, tuple):
      sorted_list = tuple(_sort(None))
      return sorted_list
    elif isinstance(iterable, dict):
      if sort_on == 'keys':
        sorted_dict = _sort(0)
        return sorted_dict
      elif sort_on == 'values':
        sorted_dict = _sort(1)
        return sorted_dict
      elif sort_on is not None:
        raise ValueError(f"Unexpected value {sort_on} for sort_on. When sorting a dict, use key or values")
    else:
      raise TypeError(f"Unexpected type {type(iterable)} for iterable. Expected a list, tuple, or dict")

"역 색인"을 만들 수도 있습니다.

from collections import defaultdict
inverse= defaultdict( list )
for k, v in originalDict.items():
    inverse[v].append( k )

이제 역함수에 값이 있습니다. 각 값에는 적용 가능한 키 목록이 있습니다.

for k in sorted(inverse):
    print k, inverse[k]

나는 이걸 생각해 냈다.

import operator    
x = {1: 2, 3: 4, 4:3, 2:1, 0:0}
sorted_x = {k[0]:k[1] for k in sorted(x.items(), key=operator.itemgetter(1))}

파이썬 3.x의 경우 : x.items() 대체하는 x.items() iteritems() .

>>> sorted_x
{0: 0, 1: 2, 2: 1, 3: 4, 4: 3}

또는 collections.OrderedDict 시도하십시오!

x = {1: 2, 3: 4, 4:3, 2:1, 0:0}
from collections import OrderedDict

od1 = OrderedDict(sorted(x.items(), key=lambda t: t[1]))

dicts ValueSortedDict 사용 :

from dicts.sorteddict import ValueSortedDict
d = {1: 2, 3: 4, 4:3, 2:1, 0:0}
sorted_dict = ValueSortedDict(d)
print sorted_dict.items() 

[(0, 0), (2, 1), (1, 2), (4, 3), (3, 4)]

업데이트 : 2015 년 12 월 5 일 Python 3.5 사용

허용 된 대답이 유용하다는 것을 OrderedDict , 표준 라이브러리 컬렉션 모듈에서 OrderedDict 를 참조 할 수 있도록 업데이트되지 않았기 때문에 실용적인 대안으로 -이 유형의 문제를 정확히 해결하도록 설계되었습니다.

from operator import itemgetter
from collections import OrderedDict

x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
sorted_x = OrderedDict(sorted(x.items(), key=itemgetter(1)))
# OrderedDict([(0, 0), (2, 1), (1, 2), (4, 3), (3, 4)])

OrderedDict 의 공식 문서는 비슷한 기능을 제공하지만 sort 함수에 람다 (lambda)를 사용한다.

# regular unsorted dictionary
d = {'banana': 3, 'apple':4, 'pear': 1, 'orange': 2}

# dictionary sorted by value
OrderedDict(sorted(d.items(), key=lambda t: t[1]))
# OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('apple', 4)])

다음과 같이 간단합니다 : sorted(dict1, key=dict1.get)

글쎄, 실제로 "사전 값으로 정렬"을 수행 할 수 있습니다. 최근 나는 코드 골프 (스택 오버 플로우 질문 코드 골프 : 단어 빈도 차트 )에서 그렇게해야했습니다. Abridged, 문제는 종류의 것이었다 : 주어진 텍스트, 각 단어가 얼마나 자주 발생하는지 계산하고, 감소하는 빈도로 분류 된 상위 단어 목록을 표시한다.

단어를 키로 사용하고 각 단어의 출현 횟수를 값으로 사용하여 사전을 구성하면 다음과 같이 단순화됩니다.

from collections import defaultdict
d = defaultdict(int)
for w in text.split():
  d[w] += 1

sorted(d, key=d.get) 와 함께 사용 빈도 sorted(d, key=d.get) 으로 sorted(d, key=d.get) 단어 목록을 얻을 수 있습니다. 정렬은 단어 발생 수를 정렬 키로 사용하여 사전 키를 반복합니다.

for w in sorted(d, key=d.get, reverse=True):
  print w, d[w]

저는 사람들이 "키로 사전을 쉽게 분류 할 수는 있지만, 가치에 따라 분류하는 방법"을 설명하기 위해이 상세한 설명을 쓰고 있습니다. OP가 그러한 문제를 해결하려고 시도했다고 생각합니다. 그리고 위의 그림과 같이 값을 기준으로 키 목록을 정렬하는 방법이 있습니다.


이것은 코드입니다.

import operator
origin_list = [
    {"name": "foo", "rank": 0, "rofl": 20000},
    {"name": "Silly", "rank": 15, "rofl": 1000},
    {"name": "Baa", "rank": 300, "rofl": 20},
    {"name": "Zoo", "rank": 10, "rofl": 200},
    {"name": "Penguin", "rank": -1, "rofl": 10000}
]
print ">> Original >>"
for foo in origin_list:
    print foo

print "\n>> Rofl sort >>"
for foo in sorted(origin_list, key=operator.itemgetter("rofl")):
    print foo

print "\n>> Rank sort >>"
for foo in sorted(origin_list, key=operator.itemgetter("rank")):
    print foo

결과는 다음과 같습니다.

기발한

{'name': 'foo', 'rank': 0, 'rofl': 20000}
{'name': 'Silly', 'rank': 15, 'rofl': 1000}
{'name': 'Baa', 'rank': 300, 'rofl': 20}
{'name': 'Zoo', 'rank': 10, 'rofl': 200}
{'name': 'Penguin', 'rank': -1, 'rofl': 10000}

로플

{'name': 'Baa', 'rank': 300, 'rofl': 20}
{'name': 'Zoo', 'rank': 10, 'rofl': 200}
{'name': 'Silly', 'rank': 15, 'rofl': 1000}
{'name': 'Penguin', 'rank': -1, 'rofl': 10000}
{'name': 'foo', 'rank': 0, 'rofl': 20000}

계급

{'name': 'Penguin', 'rank': -1, 'rofl': 10000}
{'name': 'foo', 'rank': 0, 'rofl': 20000}
{'name': 'Zoo', 'rank': 10, 'rofl': 200}
{'name': 'Silly', 'rank': 15, 'rofl': 1000}
{'name': 'Baa', 'rank': 300, 'rofl': 20}






dictionary