초기 데이터의 순서를 유지하도록 생성자를 사용하여 OrderedDict를 초기화하는 올바른 방법은 무엇입니까?


124

초기 데이터의 순서를 유지하도록 순서화 된 사전 (OD)을 초기화하는 올바른 방법은 무엇입니까?

from collections import OrderedDict

# Obviously wrong because regular dict loses order
d = OrderedDict({'b':2, 'a':1}) 

# An OD is represented by a list of tuples, so would this work?
d = OrderedDict([('b',2), ('a', 1)])

# What about using a list comprehension, will 'd' preserve the order of 'l'
l = ['b', 'a', 'c', 'aa']
d = OrderedDict([(i,i) for i in l])

질문:

  • 는 것이다 OrderedDict튜플 또는 목록 또는 등 목록 목록의 튜플의 튜플의 목록 또는 튜플의 순서를 유지 초기화 (2 & 3 위의 예)의 시간에 통과?

  • OrderedDict실제로 주문을 유지하고 있는지 확인하는 방법은 무엇입니까? a dict에 예측할 수없는 순서가 있으므로 내 테스트 벡터의 초기 순서가 예측할 수없는 사전 순서와 운 좋게 같은 경우 어떻게됩니까? 예를 들어, d = OrderedDict({'b':2, 'a':1})라고 쓰는 대신 d = OrderedDict({'a':1, 'b':2})순서가 보존되었다고 잘못 결론을 내릴 수 있습니다. 이 경우 a dict가 알파벳순으로 정렬되어 있지만 항상 사실이 아닐 수도 있습니다. 반례를 사용하여 데이터 구조가 순서를 유지하는지 여부를 검증하는 신뢰할 수있는 방법은 무엇입니까?

추신. 여기에 참고 용으로 남겨 둘 게요 "파이썬의 함수 호출의 의미는 패스에 있기 때문에 OrderedDict 생성자 및 업데이트 () 메소드를 모두 키워드 인수를 사용할 수 있지만, 순서가 손실됩니다 키워드 인자 정기적으로 정렬되지 않은 사전을 사용"

PPS : 앞으로 OrderedDict는 kwargs의 순서도 보존 할 것입니다 (예제 1) : http://bugs.python.org/issue16991


10
(비어 있지 않은) dict로 OrderedDict를 초기화하는 것은 잘못된 일이라는 것은 모호하게 아이러니합니다 .
— smci

3
python3.6 이후에도 OrderDict(b=2, a=1)적절한 방법입니다. PEP 468을 참조하십시오 .
— IvanaGyro

답변:


90

OrderedDict는 액세스 권한이있는 모든 순서를 유지합니다. 초기화를 위해 정렬 된 데이터를 전달하는 유일한 방법은 마지막 두 예에서와 같이 키-값 쌍의 목록 (또는 더 일반적으로 반복 가능)을 전달하는 것입니다. 링크 한 문서에 따르면 OrderedDict는 OrderedDict 생성자가보기 전에 순서가 제거되므로 키워드 인수 나 dict 인수를 전달할 때 순서에 액세스 할 수 없습니다.

마지막 예제에서 목록 이해력을 사용해도 아무것도 변경되지 않습니다. 사이에는 차이가 없습니다 OrderedDict([(i,i) for i in l])및 OrderedDict([('b', 'b'), ('a', 'a'), ('c', 'c'), ('aa', 'aa')]). 목록 이해력이 평가되고 목록이 생성되고 전달됩니다. OrderedDict는 그것이 어떻게 만들어 졌는지에 대해 아무것도 모릅니다.


74
# An OD is represented by a list of tuples, so would this work?
d = OrderedDict([('b', 2), ('a', 1)])

예, 작동합니다. 정의에 따라 목록은 항상 표시되는 방식으로 정렬됩니다. 이것은 목록 이해에도 적용됩니다. 생성 된 목록은 데이터가 제공된 것과 동일한 방식입니다 (즉, 목록의 소스는 결정적 set이거나 소스가 dict많 거나 많지 않음).

OrderedDict실제로 주문을 유지 하는지 확인하는 방법은 무엇입니까 ? 딕셔너리에 예측할 수없는 순서가 있기 때문에 내 테스트 벡터가 딕셔너리의 예측할 수없는 순서와 운 좋게 동일한 초기 순서를 가지면 어떻게 될까요? 예를 들어, d = OrderedDict({'b':2, 'a':1})라고 쓰는 대신 d = OrderedDict({'a':1, 'b':2})순서가 보존되었다고 잘못 결론을 내릴 수 있습니다. 이 경우 a dict가 알파벳순이라는 것을 알았지 만 항상 사실이 아닐 수도 있습니다. 즉, 카운터 예제를 사용하여 데이터 구조가 순서를 유지하는지 또는 하나가 깨질 때까지 테스트 벡터를 반복적으로 시도하는 것이 부족하지 않은지 확인하는 신뢰할 수있는 방법입니다.

참조를 위해 2- 튜플의 소스 목록을 유지하고 단위 테스트를 수행 할 때 테스트 케이스의 테스트 데이터로 사용합니다. 그것들을 반복하고 순서가 유지되는지 확인하십시오.


주문 확인 정보 : 예측할 수없는 경우 2- 튜플이 dict의 순서를 위반하는지 어떻게 확인합니까? 이것은 모든 데이터 구조에 대한 일반적인 질문입니다. 아마도이 질문에서 분리해야합니다.
— 클릭

1
본질적으로 비 결정적인 것을 결정 론적으로 깨뜨릴 수는 없습니다.
— metatoaster

1
그렇다면 그러한 것들을 테스트하는 올바른 접근 방식은 무엇일까요? 당신은 계속해서 계속 노력하고 있습니까? 프로그래머에게는 순서를 예측할 수 없지만 해시 맵이므로 '일부'알고리즘을 따르고 올바른 테스트를 통해 대응해야합니까?
— 클릭

2
을 참조하십시오 __hash__. 특히 str유형 에 대해 .
— metatoaster

정의에 따라 목록은 항상 표시되는 방식으로 정렬됩니다. 이것은 저에게 중요한 진술이었습니다. 난 그저 내 기본 2 - 튜플의 목록을 사용하기로 결정 OrderedDict내가에 목록을 변환하는 오버 헤드가되지 않도록 OrderedDict. 사전 대신 목록과 같은 요소를 반복합니다.
— Bobort
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.