目录

1.random.random()

2.random.uniform()

3.random.randrange()

4.random.randint()

5.random.choice()

6.random.shuffle()

7.random.sample()


我们先来看一看random模块中有多少个方法

而此文章要讲解的方法主要有如下几个:

1.random.random()

2.random.uniform()

3.random.randrange()

4.random.randint()

5.random.choice()

6.random.shuffle()

7.random.sample()

1.random.random()

简介:

random.random()

作用:

用于生成一个0到1的随机浮点数

注意:

生成的浮点数的范围为0<= n < 1.0

源码:

    def random(self):"""Get the next random number in the range [0.0, 1.0)."""return (int.from_bytes(_urandom(7), 'big') >> 3) * RECIP_BPF

这一句话是返回从区间[0,1)的随机浮点数

我们设计一段代码:

import random
if __name__ == '__main__':print(random.random())

控制台输出:

2.random.uniform()

random.unifor(a, b)

作用:

用于生成一个指定范围内的随机符点数,两个参数其中一个是上限,一个是下限。

注意:

如果a > b,则生成的随机数n: b <= n <= a。如果 a <b, 则 a <= n <= b

源码:

    def uniform(self, a, b):"Get a random number in the range [a, b) or [a, b] depending on rounding."return a + (b - a) * self.random()

我们发现这个方法有调用了random()方法,我们知道random()方法返回的是[0,1)的随机浮点数,那么uniform()方法,因为a不一定严格小于b,a也可能等于b,如果a=b,那么返回的就是a,又因为a也可以大于b,所以返回值范围为[a,b],为左闭右闭区间

我们设计一段代码:

import random
if __name__ == '__main__':print(random.uniform(2,4))

控制台输出:

3.random.randrange()

简介:

random.randrange(start, stop, step)

作用:

从指定范围内,按指定基数递增的集合中获取一个随机数

注意:

该方法返回的随机值是左闭右开的,也就是取不到stop的值

举例:

random.randrange(10, 30, 2),结果相当于从[10, 12, 14, 16, ... 26, 28]序列中获取一个随机数。

查看源码:

    def randrange(self, start, stop=None, step=1):"""Choose a random item from range(start, stop[, step]).This fixes the problem with randint() which includes theendpoint; in Python this is usually not what you want."""# This code is a bit messy to make it fast for the# common case while still doing adequate error checking.istart = int(start)if istart != start:raise ValueError("non-integer arg 1 for randrange()")if stop is None:if istart > 0:return self._randbelow(istart)raise ValueError("empty range for randrange()")# stop argument supplied.istop = int(stop)if istop != stop:raise ValueError("non-integer stop for randrange()")width = istop - istartif step == 1 and width > 0:return istart + self._randbelow(width)if step == 1:raise ValueError("empty range for randrange() (%d, %d, %d)" % (istart, istop, width))# Non-unit step argument supplied.istep = int(step)if istep != step:raise ValueError("non-integer step for randrange()")if istep > 0:n = (width + istep - 1) // istepelif istep < 0:n = (width + istep + 1) // istepelse:raise ValueError("zero step for randrange()")if n <= 0:raise ValueError("empty range for randrange()")return istart + istep * self._randbelow(n)

我们几行代码几行代码的看。

 首先查看前几行代码:

istart = int(start)
if istart != start:raise ValueError("non-integer arg 1 for randrange()")

这几行代码主要是对start进行处理。

我们现将传参进来的start转换为int类型,然后判断,如果istart不等于start,就抛出异常

我们来设计一段代码引出这个异常

import random
if __name__ == '__main__':print(random.randrange(1.1, 20, 2))

控制台输出:

因为我们start传参不是int类型的,所以就抛出了这个异常

接着查看这几行代码:

if stop is None:if istart > 0:return self._randbelow(istart)raise ValueError("empty range for randrange()")

这几行代码对形参stop进行处理

如果形参stop为None,我们就对istart进行判断,如果istart大于0,返回self._randbelow(istart),如果istart小于等于0,抛出异常

我们来设计一段代码来引出这个异常

import random
if __name__ == '__main__':print(random.randrange(0, None, 2))

控制台输出:

关于self._randbelow(istart)是什么意思,我没有找到源码

于是我设计了一段代码

import random
if __name__ == '__main__':print(random.randrange(2, None, 1))

发现只会出现两个结果,要么是0,要么是1,都是小于start且大于等于0的

所以_randbelow()方法返回的是小于该传入形参值的随机非负数,记住这个方法的作用,我们后面也会用到这个方法

我们接着看代码

istop = int(stop)
if istop != stop:raise ValueError("non-integer stop for randrange()")

这段代码依然是对stop进行处理,和前面判断start一样,主要作用是为了防止传入的stop值有小数

我们接着看代码

width = istop - istart
if step == 1 and width > 0:return istart + self._randbelow(width)
if step == 1:raise ValueError("empty range for randrange() (%d, %d, %d)" % (istart, istop, width))

这几行代码是对step 和 width进行处理

1.如果step == 1并且 width大于0,直接返回istart + self._randbelow(width),既然我们已经搞清楚_randbelow()方法的作用,那么这句话也就很好理解了,istart加上一个小于该序列长度的随机数。

设计一段代码:

import random
if __name__ == '__main__':print(random.randrange(1, 2, 1))

控制台输出:

在刚开始我们说randrange(start, stop, step)返回的随机数是[start,stop)左闭右开的,从这段代码我们就可以看出来,这段代码我们只能返回1。

假如我们start = 1, stop = 2,那么width = 2 - 1 = 1,而_randbelow(width)只会返回0这个数,那么istart+self._randbelow(width)取到的值只有1这个数,不会取得2,所以说返回的随机数是左闭右开的。

2.如果step == 1,这里后面的条件没有写,如果width 小于等于 0,那么就会继续抛出异常。

我们设计一段代码:

import random
if __name__ == '__main__':print(random.randrange(2, 2, 1))

控制台输出:

我们接着看代码:

        istep = int(step)if istep != step:raise ValueError("non-integer step for randrange()")if istep > 0:n = (width + istep - 1) // istepelif istep < 0:n = (width + istep + 1) // istepelse:raise ValueError("zero step for randrange()")

这几行代码是对step进行处理

将step转换成int型,如果step不能与istep,那么就抛出异常, 前面对start和stop都是这么处理的,接着对istep进行判断

如果istep > 0,n = (width + istep - 1) // istep

如果istep < 0,n = (width + istep + 1) // istep

如果istep = 0,抛出异常

我们设计一段抛出异常的代码:

import random
if __name__ == '__main__':print(random.randrange(2, 12, 0))

控制台输出:

我们接着看代码

        if n <= 0:raise ValueError("empty range for randrange()")return istart + istep * self._randbelow(n)

如果n<=0,抛出异常,我们来设计代码实现这种情况

import random
if __name__ == '__main__':print(random.randrange(8, 8, 2))

控制台输出:

而如果n > 0,那么就返回istart + istep * self._randbelow(n)

这段代码通过和n值的巧妙结合,成功根据要求返回随机值,只能说设计这段代码的人确实厉害,我们举个例子

假如start = 2,stop = 10,step = 2

计算width = stop - start = 8

n = (width + istep - 1) // istep = (8 + 2 - 1) // 2 = 9 // 2 = 4

那么最后返回的是istart + istep * self._randbelow(n)

我们知道 self._randbelow(n)可以取得的值有0,1,2,3

那么返回的值就有2 + 2 * {0,1,2,3}

2 + 2 * 0 = 2

2 + 2 * 1 = 4

2 + 2 * 2 = 6

2 + 2 * 3 = 8

取不到10,所以randrange(start, stop, step)返回的随机值是左闭右开的

设计代码:

import random
if __name__ == '__main__':print(random.randrange(2, 10, 2))

控制台输出:

自此,我们randrange()方法的源代码就看完了

4.random.randint()

random.randint(a, b)

作用:

用于生成一个指定范围内的整数。其中参数a是下限,参数b是上限

注意:

返回的随机数是左闭右闭的,即[a,b]

举例:

random.randint(2,6),结果相当于从结果相当于从[2,3,4,5,6]序列中获取一个随机数。

查看源码:

    def randint(self, a, b):"""Return random integer in range [a, b], including both end points."""return self.randrange(a, b+1)

看源码我们发现这个方法调用了randrange(a, b+1)这个方法,上面我们已经讲过randrange()这个方法了,这里为了保证右边是闭区间,所以stop = b + 1

5.random.choice()

简介:

random.choice(sequence)

作用:

从序列中获取一个随机元素

注意:

sequence在python不是一种特定的类型,而是泛指一系列的类型。list, tuple, 字符串都属于sequence

源码:

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

上面我们已经讲解了_randbelow()方法的作用,而这里_randbelow(len(seq))方法返回的是小于seq序列长度的随机数,最后返回的是序列中的一个随机元素。

我们设计一段代码:

import random
if __name__ == '__main__':lst = ['python', 'Java', 'C++', 'javascript']str = ('Hello,world!')print(random.choice(lst))print(random.choice(str))

控制台输出 :

6.random.shuffle()

简介:

random.shuffle(x[, random])

作用:

用于将一个列表中的元素打乱,即将列表内的元素随机排列

源码:

    def shuffle(self, x, random=None):"""Shuffle list x in place, and return None.Optional argument random is a 0-argument function returning arandom float in [0.0, 1.0); if it is the default None, thestandard random.random will be used."""if random is None:randbelow = self._randbelowfor i in reversed(range(1, len(x))):# pick an element in x[:i+1] with which to exchange x[i]j = randbelow(i + 1)x[i], x[j] = x[j], x[i]else:_warn('The *random* parameter to shuffle() has been deprecated\n''since Python 3.9 and will be removed in a subsequent ''version.',DeprecationWarning, 2)floor = _floorfor i in reversed(range(1, len(x))):# pick an element in x[:i+1] with which to exchange x[i]j = floor(random() * (i + 1))x[i], x[j] = x[j], x[i]

由于我还没有列表,这里就不先分析源码了

设计一段程序:

import random
if __name__ == '__main__':p = ['A', 'B', 'C', 'D', 'E']random.shuffle(p)print(p)

控制台输出:

7.random.sample()

random.sample(sequence, k)

作用:

从指定序列中随机获取指定长度的片断并随机排列。

注意:

sample函数不会修改原有序列。

源码:

    def sample(self, population, k, *, counts=None):"""Chooses k unique random elements from a population sequence or set.Returns a new list containing elements from the population whileleaving the original population unchanged.  The resulting list isin selection order so that all sub-slices will also be valid randomsamples.  This allows raffle winners (the sample) to be partitionedinto grand prize and second place winners (the subslices).Members of the population need not be hashable or unique.  If thepopulation contains repeats, then each occurrence is a possibleselection in the sample.Repeated elements can be specified one at a time or with the optionalcounts parameter.  For example:sample(['red', 'blue'], counts=[4, 2], k=5)is equivalent to:sample(['red', 'red', 'red', 'red', 'blue', 'blue'], k=5)To choose a sample from a range of integers, use range() for thepopulation argument.  This is especially fast and space efficientfor sampling from a large population:sample(range(10000000), 60)"""# Sampling without replacement entails tracking either potential# selections (the pool) in a list or previous selections in a set.# When the number of selections is small compared to the# population, then tracking selections is efficient, requiring# only a small set and an occasional reselection.  For# a larger number of selections, the pool tracking method is# preferred since the list takes less space than the# set and it doesn't suffer from frequent reselections.# The number of calls to _randbelow() is kept at or near k, the# theoretical minimum.  This is important because running time# is dominated by _randbelow() and because it extracts the# least entropy from the underlying random number generators.# Memory requirements are kept to the smaller of a k-length# set or an n-length list.# There are other sampling algorithms that do not require# auxiliary memory, but they were rejected because they made# too many calls to _randbelow(), making them slower and# causing them to eat more entropy than necessary.if isinstance(population, _Set):_warn('Sampling from a set deprecated\n''since Python 3.9 and will be removed in a subsequent version.',DeprecationWarning, 2)population = tuple(population)if not isinstance(population, _Sequence):raise TypeError("Population must be a sequence.  For dicts or sets, use sorted(d).")n = len(population)if counts is not None:cum_counts = list(_accumulate(counts))if len(cum_counts) != n:raise ValueError('The number of counts does not match the population')total = cum_counts.pop()if not isinstance(total, int):raise TypeError('Counts must be integers')if total <= 0:raise ValueError('Total of counts must be greater than zero')selections = self.sample(range(total), k=k)bisect = _bisectreturn [population[bisect(cum_counts, s)] for s in selections]randbelow = self._randbelowif not 0 <= k <= n:raise ValueError("Sample larger than population or is negative")result = [None] * ksetsize = 21        # size of a small set minus size of an empty listif k > 5:setsize += 4 ** _ceil(_log(k * 3, 4))  # table size for big setsif n <= setsize:# An n-length list is smaller than a k-length set.# Invariant:  non-selected at pool[0 : n-i]pool = list(population)for i in range(k):j = randbelow(n - i)result[i] = pool[j]pool[j] = pool[n - i - 1]  # move non-selected item into vacancyelse:selected = set()selected_add = selected.addfor i in range(k):j = randbelow(n)while j in selected:j = randbelow(n)selected_add(j)result[i] = population[j]return result

同上,就不分析源码了,我们直接设计一段代码

import random
if __name__ == '__main__':p = ['A', 'B', 'C', 'D', 'E']print(random.sample(p,4))print(p)

控制台输出:

python 从源码讲解random模块相关推荐

  1. python difflib 源码_python difflib 模块

    可以使用diff 模块对比文件的差别,然后以版本控制风格输出: [oracle@pr ~]$ more test.py import difflib text1 = """ ...

  2. VS2019编译python解释器源码及学习方法

    Python源码编译   Python是当下很火的一门编程语言,在人工智能.数据分析.后端开发等领域可谓是人人都会的语言,在用python实现各种应用服务的同时,估计很少有人去关注python的实现, ...

  3. python解释器源码 pdf_《python解释器源码剖析》第0章--python的架构与编译python

    本系列是以陈儒先生的<python源码剖析>为学习素材,所总结的笔记.不同的是陈儒先生的<python源码剖析>所剖析的是python2.5,本系列对应的是python3.7. ...

  4. nginx源码分析之模块初始化

    在nginx启动过程中,模块的初始化是整个启动过程中的重要部分,而且了解了模块初始化的过程对应后面具体分析各个模块会有事半功倍的效果.在我看来,分析源码来了解模块的初始化是最直接不过的了,所以下面主要 ...

  5. python内存管理和释放_《python解释器源码剖析》第17章--python的内存管理与垃圾回收...

    17.0 序 内存管理,对于python这样的动态语言是至关重要的一部分,它在很大程度上决定了python的执行效率,因为在python的运行中会创建和销毁大量的对象,这些都设计内存的管理.同理pyt ...

  6. 智能优化算法之遗传算法(GA)的实现(基于二进制编码,Python附源码)

    文章目录 一.遗传算法的实现思路 二.基于二进制编码方式的遗传算法的实现 1.库的导入 2.目标函数 3.个体编码函数 4.个体解码函数 5.选择函数 6.交叉函数 7.变异函数 8.算法主流程 一. ...

  7. Python查看源码

    Python查看源码 模块源码 import module module.__file__查看模块文件源码位置 module. __ name __查看模块名字 dir(module)显示模块所有方法 ...

  8. Tengine怎么去安装第三方模块、以及安装源码中的模块

    Tengine怎么去安装第三方模块 检查配置文件nginx.conf的内容编辑后是否有错误 nginx -t 有以下错误,需要下载第三方模块 nginx: [emerg] unknown direct ...

  9. C++简介源码讲解精辟版,C++入门级C++学习,C++与C的区别值得知晓

    C++简介源码讲解精辟版,C++入门级C++学习,C++与C的区别值得知晓 C语言和C++基础区别 C++标准输入和输出 命名空 1.命名空间的定义 : namespace 标识符{ } 例:name ...

最新文章

  1. 关于fseek和文件ab+打开方式的问题
  2. C语言N台服务器通信,使用socket的Linux上的C语言文件传输顺序服务器和客户端示例程序 ....
  3. boost::hana::remove_range_c用法的测试程序
  4. spring4.0之三:@RestController
  5. 使用CMD命令修改Windows本地账户密码
  6. 大小不固定的图片和多行文字的垂直水平居中
  7. JS - this,call,apply
  8. matlab程序约束条件,求Xij中i,j约束条件下的程序
  9. 360天擎默认卸载密码_装机工具老毛桃携带木马病毒 卸载安全软件进行恶意推广...
  10. Ember.js 1.0 RC6 发布,JavaScript 框架
  11. sublime cscope使用方法
  12. Python环境搭建之OpenCV(转载)
  13. 嵌入式c语言移植,嵌入式c语言位操作的移植与优化.doc
  14. UVA10341 Solve It【二分】
  15. 商用密码产品认证-智能密码钥匙
  16. c#万能视频播放器(附代码)
  17. swagger主页访问,返回报错500
  18. 中国人保为闲人谷中药科技承保产品责任险,为消费者保驾护航!
  19. 解决Mybatis报错问题:Type interface com.tjcu.dao.UserDao is not known to the MapperRegistry.
  20. CVE-2018-6794一把梭

热门文章

  1. QT5打开图片并显示
  2. 计算机专业教师演讲稿,计算机专业演讲稿2篇
  3. 解析grant connect, resource to user语句
  4. 【高精度定位】关于GPS、RTK、PPK三种定位技术的探讨
  5. cdma 复制短息到uim卡的实现
  6. 用 bat 批处理命令启动 Android Studio 自带模拟器
  7. 印度理工学院有多难考?
  8. ServU配置网络盘
  9. 如何用Markdown写论文?
  10. windows installer 窗口一直”正在取消“,无法关闭