초기 데이터의 순서를 유지하도록 생성자를 사용하여 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.