2014-05-24 3 views
3

그래서 같이 셔플 싶은 것 인 OrderedDict 있습니다왜 OrderedDict를 섞을 수 없습니까?

od = OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 4)]) 
random.shuffle(od) 

불행하게도이 (python3)를 작동하지 않습니다, 그리고 KeyError: 0 예외가 발생합니다. OrderedDict 주문을 가지고 있기 때문에

od_tmp = list(od.items()) 
random.shuffle(od_temp) 
od = OrderedDict(od_tmp) 

, 그것은 직접 정렬 할 수있는 것이 합리적인 것 같다 내가 작업 한 대안은리스트, 셔플로 변환 및 OrderedDict를 재 구축하는 것입니다. 목록으로 변환하는 것은 비효율적입니다.

질문은 다음과 같습니다

  • 위의 솔루션보다 더 좋은 방법이 있나요? (목록 만 사용하지 않고)
  • 왜 OrderedDict를 섞을 수 없습니까?

답변

3

당신은하지 random.shuffle OrderedDict random.shuffle 때문에 마음에 sequences로 작성 할 수 있습니다. 불행히도 최고의 셔플 알고리즘 (Fisher-Yates shuffle)은 임의 액세스를 효율적으로해야하지만 OrderedDict는 키를 기반으로 한 주문을 기반으로 임의 액세스를 제공하지 않습니다. 은 기본 링크 된 목록을 섞는 영리하고 빠른 방법 일 수 있습니다. 그러나 나는 전혀 알지 못합니다.

랜덤 액세스 대신 순서대로 반복되는 Fisher-Yates 셔플을 구현할 수 있지만,이 속도는 더 느려질 수 있습니다 (2 차 복잡성 및 상당히 높은 상수). 적은 사본 및 구조없고 무의미한 튜플 만 키를 셔플하는 것을 옵션은 원래 OrderedDict 재정렬 :

keys = list(od) 
random.shuffle(keys) 
for key in keys: 
    od.move_to_end(key) 

을하지만이 더 읽기 미적인지 확실하지 않다.