从非空 defaultdict 中选取一个随机元素
Picking a random element from a non-empty defaultdict
说我愿意:
import collections, random
d = collections.defaultdict(list)
d['foo'].append('bar')
然后我选择一个随机元素:
random.choice(d)
现在让我们打印 d
:
defaultdict(list, {0: [], 'foo': ['bar']})
为什么 random.choice
添加 0
作为键?
在内部这是 random.choice
所做的:
def choice(self, seq):
"""Choose a random element from a non-empty sequence."""
return seq[int(self.random() * len(seq))]
在你的例子中,长度是 1,乘法后它会产生一个范围 [0.0, 1.0)
的数字,在应用 int()
之后你会得到 0。
请注意,defaultdict
会将任何键添加到在其上访问的字典:
>>> d = collections.defaultdict(list)
>>> d['i dont exist']
[]
>>> d
defaultdict(<type 'list'>, {'i dont exist': []})
因此,您的命令以 0
结尾。
我认为该行为实际上是 未定义,因为根据文档(强调我的):
random.choice(seq)
Return a random element from the non-empty
sequence seq. If seq is empty, raises IndexError.
seq
需要是序列类型,例如list
、tuple
和range
。但是,defaultdict
是内置 dict
class 的子class,因此它是一个 mapping 类型。
而且由于序列类型只能有整数作为它们的 "keys",所以 random.choice
会查找 d[x]
并不奇怪,其中 x
是 [= 中的整数20=].
说我愿意:
import collections, random
d = collections.defaultdict(list)
d['foo'].append('bar')
然后我选择一个随机元素:
random.choice(d)
现在让我们打印 d
:
defaultdict(list, {0: [], 'foo': ['bar']})
为什么 random.choice
添加 0
作为键?
在内部这是 random.choice
所做的:
def choice(self, seq):
"""Choose a random element from a non-empty sequence."""
return seq[int(self.random() * len(seq))]
在你的例子中,长度是 1,乘法后它会产生一个范围 [0.0, 1.0)
的数字,在应用 int()
之后你会得到 0。
请注意,defaultdict
会将任何键添加到在其上访问的字典:
>>> d = collections.defaultdict(list)
>>> d['i dont exist']
[]
>>> d
defaultdict(<type 'list'>, {'i dont exist': []})
因此,您的命令以 0
结尾。
我认为该行为实际上是 未定义,因为根据文档(强调我的):
random.choice(seq)
Return a random element from the non-empty sequence seq. If seq is empty, raises IndexError.
seq
需要是序列类型,例如list
、tuple
和range
。但是,defaultdict
是内置 dict
class 的子class,因此它是一个 mapping 类型。
而且由于序列类型只能有整数作为它们的 "keys",所以 random.choice
会查找 d[x]
并不奇怪,其中 x
是 [= 中的整数20=].