2014-05-24 54 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 an OrderedDict因爲random.shuffle是用sequences來記。不幸的是,最好的隨機訪問算法(Fisher-Yates shuffle)要求隨機訪問是有效的,但OrderedDict不會根據訂單提供隨機訪問(僅基於密鑰)。有可能是一個聰明和快速的方式來洗牌底層鏈表,但我不知道任何。

您可以實現一個按順序迭代而不是隨機訪問的Fisher-Yates shuffle,但這會更慢(二次複雜性和相當高的常量)。一個選項,拷貝少,結構不無意義的元組是洗牌只是鍵,然後重新排序原始OrderedDict:

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

但我不知道這是否是更具可讀性和審美。