파이썬에서 정렬 된 키 순서로 사전을 어떻게 반복합니까?


211

다음과 같이 끝나는 기존 함수가 있습니다. 여기서 d사전은 다음과 같습니다 .

return d.iteritems()

주어진 사전에 대해 분류되지 않은 반복자를 반환합니다. key 별로 정렬 항목을 통과하는 반복자를 반환하고 싶습니다 . 어떻게합니까?

답변:


171

이것을 광범위하게 테스트하지는 않았지만 Python 2.5.2에서 작동합니다.

>>> d = {"x":2, "h":15, "a":2222}
>>> it = iter(sorted(d.iteritems()))
>>> it.next()
('a', 2222)
>>> it.next()
('h', 15)
>>> it.next()
('x', 2)
>>>

for key, value in d.iteritems(): ...반복자 대신 수행하는 데 익숙한 경우 위의 솔루션에서 여전히 작동합니다.

>>> d = {"x":2, "h":15, "a":2222}
>>> for key, value in sorted(d.iteritems()):
>>>     print(key, value)
('a', 2222)
('h', 15)
('x', 2)
>>>

Python 3.x에서는 반복자를 반환하는 d.items()대신 사용하십시오 d.iteritems().


29
사용하는 .items()대신 iteritems(): @Claudiu 말했듯이, iteritems 파이썬 3.x를 작동하지 않지만, items()파이썬 2.6에서 사용할 수 있습니다.
Remi

40
이것은 분명하지 않습니다. 실제로, items()목록을 작성하여 메모리를 사용하지만 iteritems()본질적으로 메모리를 사용하지는 않습니다. 주로 사용하는 것은 사전의 크기에 따라 다릅니다. 또한, 파이썬 3 변환 도구에 자동 파이썬 2 ( 2to3) 자동에서 변환을 담당 iteritems()하는 items(), 그래서 이것에 대해 걱정할 필요가 없습니다.
Eric O Lebigot

5
@HowerHell을 사용하면 collections.OrderedDict한 번 정렬하고 항상 정렬 된 순서로 항목을 가져옵니다.
Mark Harviston 2016 년

9
그러나 @EOL iteritems()은 메모리를 사용하지 않더라도 모든 메모리를 메모리로 가져와야 sorted()하므로 메모리 사용 items()iteritems()여기 에는 차이가 없습니다 .
Richard

8
@ 리차드 : 그것은 모든 요소가 메모리에 들어갔습니다해야한다는 사실이지만, 그들이하는 저장items()(에 의해 반환 된 목록 items()만에 한 번, 그리고 정렬 된 목록에서) iteritems()(정렬 된 목록 만 해당).
Eric O Lebigot

83

sorted()기능을 사용하십시오 :

return sorted(dict.iteritems())

정렬 된 결과에 대해 실제 반복자를 원하면 sorted()목록을 리턴하므로 다음을 사용하십시오.

return iter(sorted(dict.iteritems()))

<type 'exceptions.TypeError'> : iter ()가 'list'유형의 반복자를 반환하지 않음
mike

변수 이름으로 "dict"를 사용하기 때문일 수 있습니다. "dict"는 실제로 사전의 유형 이름입니다. 여기에 "mydict"와 같은 다른 이름과 짜잔을 사용하십시오.
utku_karatas

1
그래도 작동이 안되는. 긍정적 인 sorted ()가 일반 목록이 아닌 다른 반복자를 반환합니까?
mike

이 예외는 언제 어디서 발생합니까? 문제없이 목록을 반복 할 수 있습니다

1
동의합니다. 파일에서 줄을 건너 뛸 때를 제외하고 .next ()를 직접 호출한다고 생각하지 않습니다. 우리 ITER (분류 (dict.iteritems ())) 솔루션 종료 기본 반복자 혜택이 :) 잃은 것 같다, 그래서 어쨌든 "분류 ("단계에서 메모리에 전체 DICT의 사본을 최대

39

dict의 키는 해시 테이블에 저장되므로 '자연 순서', 즉 psuedo-random입니다. 다른 주문은 dict 소비자의 개념입니다.

sorted ()는 항상 dict가 아닌 목록을 반환합니다. dict.items ()를 전달하면 (튜플 목록을 생성 함) 루프에서 사용할 수있는 튜플 목록 [(k1, v1), (k2, v2), ...]을 반환합니다. dict과 매우 흡사하지만 어쨌든 dict은 아닙니다 !

foo = {
    'a':    1,
    'b':    2,
    'c':    3,
    }

print foo
>>> {'a': 1, 'c': 3, 'b': 2}

print foo.items()
>>> [('a', 1), ('c', 3), ('b', 2)]

print sorted(foo.items())
>>> [('a', 1), ('b', 2), ('c', 3)]

다음은 루프에서 딕트처럼 느껴지지만 k, v로 압축이 풀린 튜플 목록입니다.

for k,v in sorted(foo.items()):
    print k, v

대략 다음과 같습니다.

for k in sorted(foo.keys()):
    print k, foo[k]

좋아, 그러나 Dict 나 List를 원하지 않고 Iterator를 원한다. Iterator가 되려면 어떻게해야합니까?
mike

2
sorted(foo.keys())sorted(foo)사전은 반복 될 때 키를 반환하므로 (반복 가능 foo.keys()항목의 sorted()구현 방법에 따라 중간 목록 을 작성하도록 강요하지 않는 이점이 있으므로) 등가 방식보다 낫습니다 .
Eric O Lebigot

k in sorted(foo.keys()):키를 당기거나 for k,v in sorted(foo.items()):사전에 추측 한 사전 목록 쌍의 사본을 반환하는 속도 및 / 또는 메모리에 더 좋은 Wondersorted(foo.keys())
CrandellWS

1
@CrandellWS : 시간 질문에 대답하는 가장 좋은 방법은 Python timeit 모듈을 사용하는 것입니다.
피터 로웰

1
@frank-간단한 답변 : 아니요. dict는 실제 키가 제공된 키 값의 해시 인 배열입니다 . 일부 구현은 상당히 예측 가능하고 일부는이 계약을 만들 수도 있지만 해시 순서와 관련해서는 아무것도 고려하지 않습니다 . 3.6+ 동작에 대한 자세한 내용은 이 게시물 을 참조하십시오 . 특히 첫 번째 대답에 유의하십시오.
피터 로웰

31

그렉의 대답이 맞습니다. 파이썬 3.0에서는해야 할 것입니다

sorted(dict.items())

iteritems사라질 것입니다.


그것은 나에게 실패합니다 : <type 'exceptions.TypeError'> : iter ()가 'list'유형의 반복자를 반환하지 않음
mike

3
"미래에 호버 보드를 갖기 때문에 자동차를 사용하지 마십시오"
JJ

7

이제 OrderedDictPython 2.7에서도 사용할 수 있습니다 .

>>> from collections import OrderedDict
>>> d = OrderedDict([('first', 1),
...                  ('second', 2),
...                  ('third', 3)])
>>> d.items()
[('first', 1), ('second', 2), ('third', 3)]

여기 2.7 버전 의 새로운 기능 페이지와 OrderedDict API가 있습니다.


그러면 정렬 된 순서가 아닌 알파벳 순서대로 키, 값이 삽입 된 순서대로 반환됩니다.
Tony Suffolk 66

5

일반적으로 다음과 같이 dict을 정렬 할 수 있습니다.

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

d.iteritems () 대신 "drop in replacement"가있는 특정 문제의 경우 다음과 같은 함수를 추가하십시오.

def sortdict(d, **opts):
    # **opts so any currently supported sorted() options can be passed
    for k in sorted(d, **opts):
        yield k, d[k]

끝줄이

return dict.iteritems()

return sortdict(dict)

또는

return sortdict(dict, reverse = True)

5
>>> import heapq
>>> d = {"c": 2, "b": 9, "a": 4, "d": 8}
>>> def iter_sorted(d):
        keys = list(d)
        heapq.heapify(keys) # Transforms to heap in O(N) time
        while keys:
            k = heapq.heappop(keys) # takes O(log n) time
            yield (k, d[k])


>>> i = iter_sorted(d)
>>> for x in i:
        print x


('a', 4)
('b', 9)
('c', 2)
('d', 8)

이 방법은 여전히 ​​O (N log N) 정렬을 갖지만 짧은 선형 힙화 후에는 정렬 된 순서대로 항목을 생성하므로 항상 전체 목록이 필요하지 않을 때 이론적으로 더 효율적입니다.



3

sorted는 목록을 반환하므로 목록을 반복하려고 할 때 오류가 발생하지만 dict을 주문할 수 없으므로 목록을 처리해야합니다.

더 큰 코드 컨텍스트가 무엇인지 알지 못하지만 결과 목록에 반복자를 추가 할 수 있습니다. 이 같은 어쩌면? :

return iter(sorted(dict.iteritems()))

당연히 당신은 튜플을 되 찾을 것입니다.

예 : 당신의 dict was : {'a':1,'c':3,'b':2} sorted는 그것을 목록으로 바꿉니다.

[('a',1),('b',2),('c',3)]

따라서 실제로 목록을 반복 할 때 문자열과 정수로 구성된 튜플을 다시 가져 오지만 적어도 반복 할 수는 있습니다.


2

CPython 2.x를 사용하고 있고 큰 사전 mydict가 있다고 가정하면 sorted (mydict)를 사용하면 sorted가 mydict의 키 목록을 정렬하므로 속도가 느려집니다.

이 경우 C 구현을 포함하는 내 ordereddict 패키지를보고 싶을 수도 있습니다. sorteddict . 특히 사전 수명의 다른 단계 (예 : 요소 수)에서 정렬 된 키 목록을 여러 번 경우.

http://anthon.home.xs4all.nl/Python/ordereddict/

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