【问题标题】:Why can't OrderedDict be shuffled?为什么 OrderedDict 不能被洗牌?
【发布时间】:2014-05-24 20:13:24
【问题描述】:

我有一个 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?

【问题讨论】:

    标签: python-3.x shuffle ordereddictionary


    【解决方案1】:

    你不能 random.shuffle 一个 OrderedDict 因为 random.shuffle 是在考虑 sequences 的情况下编写的。不幸的是,最好的 shuffle 算法(Fisher-Yates shuffle)需要随机访问才能有效,但 OrderedDict 不提供基于顺序的随机访问(仅基于密钥)。 可能有一种巧妙而快速的方法来打乱底层链表,但我不知道。

    您可以实现按顺序迭代的 Fisher-Yates shuffle,而不是进行随机访问,但这会更慢(二次复杂度和相当高的常数)。复制较少且不构造无意义的元组的一种选择是仅对键进行洗牌,然后对原始 OrderedDict 重新排序:

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

    但我不确定这是否更具可读性和美观性。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-11-06
      • 2016-04-07
      • 1970-01-01
      • 1970-01-01
      • 2021-02-11
      • 2018-04-21
      • 2015-07-25
      • 2016-03-22
      相关资源
      最近更新 更多