知行编程网知行编程网  2022-01-02 20:02 知行编程网 隐藏边栏 |   抢沙发  68 
文章评分 0 次,平均分 0.0

利用Python实现产生无重复随机数字

今天在和朋友聊天时朋友提出了一个问题:如何利用Python产生一串无重复的随机数字,注意所产生的数字必须是无重复随机的。

我们知道产生随机数,Python有一个模块是random,只需要import random然后调用其方法就可以了,但是如何做到无重复呢?下面是我们总结的几种可行的方法,其中最后一种方法的做法十分巧妙,建议读者思考和理解。

实现

random的sample函数

在random模块中,直接调用sample函数即可解决问题,该方法的参数如下

如上,该方法用于从population序列中随机抽取k个独立的元素,让我们来实践一下:

如上结果所示,即可实现产生无重复的随机数字。

set去重

一讲到无重复,我们很容易就想到了set,因为set里的元素是不重复的,set最经常的一个应用就是利用其来进行序列的去重,如下例子:

利用该性质,我们既可以实现列表去重,也可以很方便地统计列表中独立元素的个数。

所以利用set去产生无重复随机数字时,我们可以利用set保存所产生的随机数字,每次产生一个随机数字,检查其是否在set中,如果不在的话再加入set,如果在的话则重新产生随机数字,看如下代码:

如上,就可以得到我们想要的number个随机数。

但是此法有一个弊端就是:所需要的随机数个数逼近随机数的可选范围时,可想而知,每次我们产生的随机数重复的概率将大大增加,加大了时间开销,下面将介绍的方法可以比较完美地解决该问题。

利用列表抽取无重复随机数字

我们可以将要抽取的随机数范围先生成一个列表,再随机生成列表下标,pop出对应下标的元素加入结果集即可,具体实现如下:

如上,我们首先根据随机数的产生范围生成一个列表test_list,然后随机生成test_list的下标,并pop出对应下标的元素加入到结果集result_list中。

此处需要注意的是:每次pop出一个元素,列表的长度会减 1,所以每次循环我们需要减少随即下标的产生范围。

那么有没有一个方法,不需要pop出列表元素以及每次都要将列表长度减去 1 呢?当然是有的。

我们知道,在上面的方法中,在随机数的产生范围表test_list中,如果一个元素被加入到结果集中,该元素便不可能再次出现,我们的法是将其pop出并将下次下标产生的范围减少 1,这提示我们可以将两者结合起来。

因为每次下标产生范围会减少 1,及当前下标以后的下标是无法取到的,那么我们就可以无需pop出列表元素,而将pop的元素与最后一个下标的元素交换即可,这样由于下一次下标产生范围会减少 1,所以被置换到后面的元素是取不到的,利用这个思想我们就可以完成去重

但是我们还没有解决下标产生范围减 1的问题,其实我们可以换一个思路:顺序遍历,然后在当前元素及之后的元素中挑选随机数,将其与当前元素做置换即可,具体实现如下:

如上,我们顺序遍历random_list,然后在当前元素及之后的元素中挑选随机数,将其与当前元素做置换,重复此过程,直到产生足够的随机数即可。

列表取用元素小tips

在产生了随机数之后(假设以列表形式保存),我们如何取用呢?

通常我们的取用方法是顺序遍历过去,对于所有以列表形式保存的数据的取用方法都是如此,可以用Python的 for in 进行遍历,也可以用下标遍历,如下:

也可以用下标:

如上,如果我们用 for in 进行便利的话,其元素只能是顺序遍历而不能后退。

而如果我们用下标进行遍历,我们可以对下标 index 根据我们的需要进行控制,进而可以实现输出后面的元素。

而如果需要同时取得下标即下标对应的元素(上面所讲的下标遍历同时在输出下标也可以实现),并且不需要往后的话,我们还可以使用 enumerate 方法作用于列表返回其下标及对应的元素,如下:

那么对于元素的取用,我们有没有其他写法?我们首先联想到的就是:迭代器。

迭代器也是用来保存元素的,而且其对元素的遍历只能往前,不能后退。可以使用 next() 函数进行遍历,也可以用迭代器的 __ next __() 方法取得下一个元素。

所以我们可以将列表包装成 iter 对象,然后用 next 去调用其中的元素,具体如下:

也可以用 __ next __() 方法取得下一个元素:

但应用此方法时我们需要特别注意的是:当迭代器取到最后一个元素后,即迭代器已无 next 元素时间,再次取用下一个元素会抛出 StopIteration 异常,如下:

如上即是列表取用元素的常用方法,而最后一个将列表包装成迭代器看似没有多大用处,但是在某些应用场合会有出其不意的效果。

总结

以上就是本篇的全部内容,其实利用Python实现产生无重复随机数字的方法除了上面所讲,一定还有其他的方法,读者可以自己去思考。

在上面所讲的实现方法中,我们要重点去理解利用列表抽取无重复随机数字的方法,其将抽取过的元素与当前元素进行置换的思想是十分巧妙的。

这提示我们合理分配空间,以达到空间的最大利用率,从而节省内存。

本文为原创文章,版权归所有,欢迎分享本文,转载请保留出处!

知行编程网
知行编程网 关注:1    粉丝:1
这个人很懒,什么都没写

发表评论

表情 格式 链接 私密 签到
扫一扫二维码分享