我有一个想要像这样洗牌的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有订单,因此能够直接对其进行排序似乎是合理的。转换为列表效率低下。
问题是:
答案 0 :(得分:4)
您不能random.shuffle
订购OrderDict,因为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)
但我不确定这是否更具可读性和美感。