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
从这个结果可以看到:
2 9 1 4
;2 2 2 2
;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真实的原理有偏差,但是我觉得这个思想还是挺符合目前这些个实例的逻辑。