深入分析random模块下的choice()方法

random.choice()

作用:从序列的元素中返回一个随机挑选的元素。

语法:random.choice(seq)

  • seq:序列,该序列可以用len()求出长度,且可以通过下标访问(因为取随机要依赖于下标)。
  • 文档注释:Choose a random element from a non-empty sequence. raises IndexError if seq is empty
mylist = ['我', 5, 7, 13]
print(random.choice(mylist))  # 13

说到序列sequence,很自然的想到字符串、列表、元组、字典、集合。很多帖子讲序列也是这些内容,那么我们就用choice()试一试

mydict = {'书名': '围城', '作者': '钱钟书', '价格': 18.8}
print(random.choice(mydict))
# 结果:KeyError: 2

呀!报错了,这是为什么呢?难道字典不是序列?
看了多个帖子,基本都是开头给出序列的定义,其中之一就是可以用下标访问,然而后面就把字典也写进去,也不说其中的道道。虽然我也给不出序列准确的定义,但是就choice()方法而言,这里的sequence必须满足两个条件。

  • 可以用len()来求出长度
  • 可以用下标访问

这里先给出choice的源码

    def choice(self, seq):
        """Choose a random element from a non-empty sequence."""
        # raises IndexError if seq is empty
        return seq[self._randbelow(len(seq))]

返回值是:seq[self._randbelow(len(seq))]。这里不需要知道它具体到底干了什么,只需要明白,我调用了choice然后该方法返回给我一个东西。
len(),我们不用想都知道它是求长度的
[],中括号,我们稍稍想一下就知道这是通过下标去访问seq里面的元素

好,现在说它的工作原理,它是先对我们传进去的seq参数求出长度,确定下标的上限(下限就不用了求了,是0开始),然后调用了一个爱啥啥的东西(self._randbelow),这个‘爱啥啥’返回的是一个下标。高人说话都是说一半留一半,虽然我不是高人,但是这方面也想向高人看齐。
那么,接下的事就交给诸位吧。