3

次のようにシャッフルしたい 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 をシャッフルできないのはなぜですか?
4

1 に答える 1

4

シーケンスを念頭に置いて書かれてrandom.shuffleいるため、 OrderedDictはできません。残念ながら、最良のシャッフル アルゴリズム (Fisher-Yates shuffle) を効率的に使用するにはランダム アクセスが必要ですが、OrderedDict は順序に基づくランダム アクセスを提供しません (キーのみに基づく)。基礎となるリンクされたリストをシャッフルするための巧妙で迅速な方法があるかもしれませんが、私は知りません。random.shuffle

ランダム アクセスを行う代わりに、順番に反復する Fisher-Yates シャッフルを実装することもできますが、これはさらに遅くなります (2 次の複雑さと非常に高い定数)。コピーを減らし、無意味なタプルを構築しないオプションは、キーのみをシャッフルしてから、元の OrderedDict を並べ替えることです。

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

しかし、これがより読みやすく美的であるかどうかはわかりません。

于 2014-05-24T20:27:23.020 に答える