对random.seed()的理解

random.seed()

random.seed() 会改变随机生成器的种子;传入的数值用于指定随机数生成时所用算法开始时所选定的整数值,如果使用相同的seed()值,则每次生成的随机数都相同;如果不设置这个值,则系统会根据时间来自己选择这个值,此时每次生成的随机数会因时间的差异而有所不同。

昨天在看书的时候对一段代码不是很理解:

import random
import bisect

SIZE = 7
random.seed(1729) 
my_list = []
for i in range(SIZE):
    new_item = random.randrange(SIZE * 2)
    bisect.insort(my_list, new_item)
    print('%2d ->' % new_item, my_list)

OUTPUT:

10 -> [10]
 0 -> [0, 10]
 6 -> [0, 6, 10]
 8 -> [0, 6, 8, 10]
 7 -> [0, 6, 7, 8, 10]
 2 -> [0, 2, 6, 7, 8, 10]
10 -> [0, 2, 6, 7, 8, 10, 10]

其中new_item = random.randrange(SIZE * 2)返回的随机数列一直是相同不变的,后来发现random.randrange()产生的随机数之所以会固定以因为random.seed()这个方法的原因。

random.seed()方法比较官方的说明在开头也已经写出来了;那个文字性的描述对我来说还是过于的抽象,在查看了很多博客后我又测试了好多个实例,最后对这个方法总算是有一点明白了吧。


第一个例子,我把上面的代码简化了一下:

random.seed(1)
for i in range(1, 5):
    print(random.randrange(10))

OUTPUT1 :

2
9
1
4

每次运行后,输出的结果都是一个相同的序列。


第二个例子:将random.seed(1)放进了循环体内部

for i in range(1, 5):
    random.seed(1)
    print(random.randrange(10))

OUTPUT2 :

2
2
2
2

这次每次输出的序列也都是相同的,只不过序列的元素也是一样的都是2。


开始弄到这里我还是一头雾水,但是偶然间我做了第三个实例后,好像就有点明白了。

random.seed(1)
print(random.randrange(10))
for i in range(1, 5):
    print(random.randrange(10))

OUTPUT3 :

2
9
1
4
1

最后,将三个OUTPUT的结果放在一起来看一下可能就会清晰很多:

OUTPUT :

2   2   2   
9   2   9
1   2   1
4   2   4
        1

从这个结果可以看到:

  1. random.seed()放在循环外是一个序列:2 9 1 4
  2. random.seed()放在循环内部的时候则是另外一个序列:2 2 2 2
  3. 在random.seed()下面先打印一个随机数然后在循环的到的是另外一个序列:2 9 1 4 1;

三种方式的开头都是2,而1和3的前四个数又是一样的,只不过3多打印了一次,这里我们再加入一个例子来证明我的想法:

random.seed(1)
for i in range(1, 6):
    print(random.randrange(10))

OUTPUT:

2
9
1
4
1

将例子1的循环次数加1,从而得到和3一样的输出次数,最后得出的结果是一模一样的。


总结:

目前我对于random.seed()函数的理解是这样的:

  • random.seed()的返回值是None;但是我觉得他会隐藏的构建一个类似列表的数据结构,这个列表的长度应该是特别大的(我曾将循环次数加到6000次发现返回的结果依旧是相同的),根据你在seed()中传入的参数不同,seed会构建一个元素不同的列表,而random.randrange()会迭代这个列表,按照列表的顺序将每个元素依次提出来作为随机数算法的初始值。这也就是为什么在例子1中设置了一个seed()后每次返回的随机序列都是相同的,以在例子3的结果和例子1的结果也是相同的。

  • 而当我把seed()放进循环中去的时候,依旧会构建一个list,只不过list在循环里面,每次都会被重置,而当random.randrange()每次去迭代的时候由于list一直被循环重置,所以random.randrange()在迭代列表时的指针也就会一直被重定向到首元素,也就一直去使用list中的第一个元素作为随机数算法的开始整数,因此得到的随机数序列就一直是基于list中的第一个元素求得的随机数算法的值2。

上面的想法应该会和seed真实的原理有偏差,但是我觉得这个思想还是挺符合目前这些个实例的逻辑。


猜你喜欢

转载自blog.csdn.net/weixin_43901998/article/details/101602411