【问题标题】:random.choice broken with dictsrandom.choice 被字典破坏
【发布时间】:2013-05-08 02:28:02
【问题描述】:

random.choice 有一个限制,即输入必须是一个序列。这会在dict 上导致不明显和毛茸茸的行为:

>>> d = {0: 'spam', 1: 'eggs', 3: 'potato'}
>>> random.choice(d)
'spam'
>>> random.choice(d)
'eggs'
>>> random.choice(d)
'spam'
>>> random.choice(d)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/random.py", line 274, in choice
    return seq[int(self.random() * len(seq))]  # raises IndexError if seq is empty
KeyError: 2

此外,它在setcollections 模块中的一些其他容器上根本不起作用。

除了我认为random.choice 的实现是球(没有充分的理由为什么random.choice(d) 不应该以明显的方式工作)之外,什么是从非随机选择中获得随机选择的pythonic 方式- 序列收集?

我考虑过random.choice(list(d))random.sample(d, 1)[0],但希望可能有其他不那么丑陋的方法。

可以对random.choice 进行猴子修补以“正常工作”,同时不会破坏或大幅降低当前序列行为的效率吗?

【问题讨论】:

  • 好吧,真的……给定一个dict会如何选择一个随机值?它必须内置到 dict 中才能比一般的 d[random.choice(d.keys())] 更有效。
  • @Rynah 而不是这个:d[random.choice(d.keys())],我认为这更有意义:random.choice(d.values())
  • @rynah 我的观点是random.choice(d) 会选择一个随机键,而不是随机值。这将更符合infor 关键字对dicts 键的操作方式。如果你想要一个随机值,你可以使用random.choice(d.values())(顺便说一句,这在 python 3 上不起作用)。
  • 正如@rrenaud 所说,它仍然需要内置到dict 中才能更高效。

标签: python random dictionary


【解决方案1】:

您可以在 2006 年的 Python 错误跟踪器上看到 this thread 关于 random.choice 不适用于集合。在算法上可以让它以相同的渐近效率工作,但它需要来自 set/dict 数据结构的自定义支持,或者接口中的新方法。 python 开发人员认为不需要。

【讨论】:

  • 那么,如何让它与 dicts/sets 一起正常工作,但对序列保持相同的效率?
  • @wim 我认为您需要自定义实现以保持相同的效率,就像这样 - stackoverflow.com/questions/10840901/…。你可以随时根据自己的需求选择dict.keys()list(set),但我想这不是你想要的。
  • Tim Peters 的这条评论告诉我们:“不成文的承诺是,在长度为 N 的序列上的选择将花费 O(1) 时间和 O(1) 空间。”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-09-02
  • 2018-10-07
  • 2011-01-02
  • 2021-07-16
  • 2011-04-29
  • 2020-02-15
相关资源
最近更新 更多