Python3标准库:random伪随机数生成器

1. random伪随机数生成器

random模块基于Mersenne Twister算法提供了一个快速伪随机数生成器。原来开发这个生成器是为了向蒙特卡洛模拟生成输入,Mersenne Twister算法会生成大周期近均匀分布的数,因此适用于大量不同类型的应用。

1.1 生成随机数

random()函数从所生成的序列返回下一个随机的浮点值。返回的所有值都落在0<=n<1.0区间内。

import random

for i in range(5):
    print(‘%04.3f‘ % random.random(), end=‘ ‘)
print()

重复运行这个程序会产生不同的数字序列。

要生成一个指定数值区间内的数,则要使用uniform()。

import random

for i in range(5):
    print(‘{:04.3f}‘.format(random.uniform(1, 100)), end=‘ ‘)
print()

传入最小值和最大值,uniform()会使用公式min+(max-min)*random()来调整random()的返回值。

1.2 指定种子

每次调用random()都会生成不同的值,并且在一个非常大的周期之后数字才会重复。这对于生成唯一值或变化的值很有用,不过有些情况下可能需要提供相同的数据集,从而以不同的方式处理。对此,一种技术是使用一个程序生成随机值,并保存这些随机值,以便在另一个步骤中再做处理。不过,这对于量很大的数据来说可能并不实用,所以random包含了一个seed()函数,可以用来初始化伪随机数生成器,使它能生成一个期望的值集。

import random

random.seed(1)

for i in range(5):
    print(‘{:04.3f}‘.format(random.random()), end=‘ ‘)
print()

种子(seed)值会控制由公式生成的第一个值,该公式可用来生成伪随机数。由于公式是确定的,所以改变种子后便设置了将生成的整个序列。seed()的参数可用是任意的可散列对象。默认为使用一个平台特定的随机源(如果有的话)。但如果没有这样一个随机源,则使用当前时间。

1.3 保存状态

random()使用的伪随机算法的内部状态可以保存,并用于控制后续生成的随机数。如果在继续生成随机数之前恢复前一个状态,则会减少出现重复的可能性,即避免出现之前输入中重复的值或值序列。getstate()函数会返回一些数据,以后可以借助setstate()利用这些数据重新初始化伪随机数生成器。

import random
import os
import pickle

if os.path.exists(‘state.dat‘):
    # Restore the previously saved state
    print(‘Found state.dat, initializing random module‘)
    with open(‘state.dat‘, ‘rb‘) as f:
        state = pickle.load(f)
    random.setstate(state)
else:
    # Use a well-known start state
    print(‘No state.dat, seeding‘)
    random.seed(1)

# Produce random values
for i in range(3):
    print(‘{:04.3f}‘.format(random.random()), end=‘ ‘)
print()

# Save state for next time
with open(‘state.dat‘, ‘wb‘) as f:
    pickle.dump(random.getstate(), f)

# Produce more random values
print(‘\nAfter saving state:‘)
for i in range(3):
    print(‘{:04.3f}‘.format(random.random()), end=‘ ‘)
print()

getstate()返回的数据是一个实现细节,所以这个例子用pickle将数据保存到一个文件;否则,它会把伪随机数生成器当作一个黑盒。如果程序开始时这个文件存在,则加载原来的状态并继续。每次运行时都会在保存状态之前和之后生成一些数,以展示恢复状态会使生成器再次生成同样的值。

第一次:

第二次:

1.4 随机整数

random()将生成浮点数。可以把结果转换为整数,不过直接使用randint()生成整数会更方便。

import random

print(‘[1, 100]:‘, end=‘ ‘)

for i in range(3):
    print(random.randint(1, 100), end=‘ ‘)

print(‘\n[-5, 5]:‘, end=‘ ‘)
for i in range(3):
    print(random.randint(-5, 5), end=‘ ‘)
print()

randint()的参数是值的闭区间的两端。这些数可以是正数或负数,不过第一个值要小于第二个值。

randrange()是从区间选择值的一种更一般的形式。

import random

for i in range(3):
    print(random.randrange(0, 101, 5), end=‘ ‘)
print()

除了开始值(start)和结束值(stop),randrange()还支持一个步长(step)参数,所以它完全等价于从range(start,stop,step)选择一个随机值。不过randrange更高效,因为它并没有真正构造区间。

1.5 选择随机元素

随机数生成器有一种常见用法,即从一个枚举值序列中选择元素,即使这些值并不是数字。random包括一个choice()函数,可以从一个序列中随机选择。下面这个例子模拟硬币10000此来统计多少次面朝上,多少次面朝下。

import random
import itertools

outcomes = {
    ‘heads‘: 0,
    ‘tails‘: 0,
}
sides = list(outcomes.keys())

for i in range(10000):
    outcomes[random.choice(sides)] += 1

print(‘Heads:‘, outcomes[‘heads‘])
print(‘Tails:‘, outcomes[‘tails‘])

由于只允许两个结果,所以不必使用数字然后再进行转换,这里对choice()使用了单词“heads”(表示面朝上)和“tails”(表示面朝下)。结果以表格形式存储在一个字典中,使用结果名作为键。

1.6 排列

要模拟一个扑克牌游戏,需要把一副牌混起来,然后向玩家发牌,同一张牌不能多次使用。使用choice()可能导致同一张牌被发出两次,所以,可以用shuffle()来洗牌,然后在发各张牌时删除所发的牌。

import random
import itertools

FACE_CARDS = (‘J‘, ‘Q‘, ‘K‘, ‘A‘)
SUITS = (‘H‘, ‘D‘, ‘C‘, ‘S‘)

def new_deck():
    return [
        # Always use 2 places for the value, so the strings
        # are a consistent width.
        ‘{:>2}{}‘.format(*c)
        for c in itertools.product(
            itertools.chain(range(2, 11), FACE_CARDS),
            SUITS,
        )
    ]

def show_deck(deck):
    p_deck = deck[:]
    while p_deck:
        row = p_deck[:13]
        p_deck = p_deck[13:]
        for j in row:
            print(j, end=‘ ‘)
        print()

# Make a new deck, with the cards in order
deck = new_deck()
print(‘Initial deck:‘)
show_deck(deck)

# Shuffle the deck to randomize the order
random.shuffle(deck)
print(‘\nShuffled deck:‘)
show_deck(deck)

# Deal 4 hands of 5 cards each
hands = [[], [], [], []]

for i in range(5):
    for h in hands:
        h.append(deck.pop())

# Show the hands
print(‘\nHands:‘)
for n, h in enumerate(hands):
    print(‘{}:‘.format(n + 1), end=‘ ‘)
    for c in h:
        print(c, end=‘ ‘)
    print()

# Show the remaining deck
print(‘\nRemaining deck:‘)
show_deck(deck)

这些扑克牌被表示为字符串,包括面值和一个表示花色的字母。要创建发出的“一手牌”,可以一次向4个列表分别增加一张牌,然后从这副牌中将发出的牌删除,使这些牌不会再次发出。

1.7 采样

很多模拟需要从大量输入值中得到随机样本。sample()函数可以生成无重复值的样本,并且不会修改输入序列。下面的例子会打印系统字典中单词的一个随机样本。

words.txt

pear
apricot
grape
pineapple
apple
peach
banana
plum
watermelon
lemon
orange
mango
strawberry

Demo.py

import random

with open(‘words.txt‘, ‘rt‘) as f:
    words = f.readlines()
words = [w.rstrip() for w in words]

for w in random.sample(words, 5):
    print(w)

第一次:

第二次:

1.8 多个并发生成器

除了模块级函数,random还包括一个Random类以管理多个随机数生成器的内部状态。之前介绍的所有函数都可以作为Random实例的方法得到,并且每个实例都可以被单独初始化和使用,而不会干扰其他实例返回的值。

import random
import time

print(‘Default initializiation:\n‘)

r1 = random.Random()
r2 = random.Random()

for i in range(3):
    print(‘{:04.3f}  {:04.3f}‘.format(r1.random(), r2.random()))

print(‘\nSame seed:\n‘)

seed = time.time()
r1 = random.Random(seed)
r2 = random.Random(seed)

for i in range(3):
    print(‘{:04.3f}  {:04.3f}‘.format(r1.random(), r2.random()))

如果系统上设置了很好的原生随机值种子,那么实例会有独特的初始状态。不过,如果没有一个好的平台随机值生成器,那么不同实例往往会以当前时间作为种子,并因此生成相同的值。

1.9 SystemRandom

有些操作系统提供了一个随机数生成器,可以访问更多能引入生成器的信息源。random通SystemRandom类提供了这个特性,该类与Random的API相同,不过使用os.urandom()生成值,该值会构成所有其他算法的基础。

import random
import time

print(‘Default initializiation:\n‘)

r1 = random.SystemRandom()
r2 = random.SystemRandom()

for i in range(3):
    print(‘{:04.3f}  {:04.3f}‘.format(r1.random(), r2.random()))

print(‘\nSame seed:\n‘)

seed = time.time()
r1 = random.SystemRandom(seed)
r2 = random.SystemRandom(seed)

for i in range(3):
    print(‘{:04.3f}  {:04.3f}‘.format(r1.random(), r2.random()))

SystemRandom产生的序列是不可再生的,因为其随机性来自系统,而不是来自软件状态(实际上,seed()和setstate()根本不起作用)。

原文地址:https://www.cnblogs.com/liuhui0308/p/12416380.html

时间: 2024-10-07 15:31:18

Python3标准库:random伪随机数生成器的相关文章

python的标准库 ----random

在python中random是一个获取随机数的一个标准库.使用时,直接import random即可. import random print(random.random()) #返回0-1之间的随机浮点数>>>0.3025160551374695 print(random.randint(1,100)) #返回1-100之间的随机整数[1,100]>>>82 print(random.randrange(1,10,2)) #返回1-10之间的随机整数,步长=2, 联想

Python3标准库

文本 1. string:通用字符串操作 2. re:正则表达式操作 3. difflib:差异计算工具 4. textwrap:文本填充 5. unicodedata:Unicode字符数据库 6. stringprep:互联网字符串准备工具 7. readline:GNU按行读取接口 8. rlcompleter:GNU按行读取的实现函数 二进制数据 9. struct:将字节解析为打包的二进制数据 10. codecs:注册表与基类的编解码器 数据类型 11. datetime:基于日期与

标准库random

random - Random variable generators. 随机变量生成器 class Random(_random.Random) -- Random number generator base class used by bound module functions. 以下是所有的random的方法: 1 import random 2 print(random.random()) #生成一个0-1之间的浮点数随机数[0,1] 3 print(random.randint(1,

Python基础--人们一些最爱的标准库(random time)

Python继续! random 包括返回随机数的函数. 这里跟C++一样,产生的是伪随机数,并非全然随机数. random中一些重要的函数: random() 返回0<n<=1的随机数n getrandbits(n) 以长整型形式返回n个随机位 uniform(a, b) 返回随机数n, a<=n<b choice(seq) 从序列seq中返回任意元素 shuffle(seq[,random]) 原地指定序列seq sample(seq, n) 从序列seq中选择n个随机且独立的

python标准库-random学习

参考资料:Python 2.7.7 documentation 参考工具:http://translate.google.cn/ random模块学习 一.Bookkeeping functions(几乎没看懂)     random.seed([x]) Initialize the basic random number generator     random.getstate() Return an object capturing the current internal state o

4.Python3标准库--算法

(一)functools:管理函数的工具 import functools ''' functools模块提供了一些工具来管理或扩展和其他callable对象,从而不必完全重写 ''' 1.修饰符 from functools import partial ''' functools模块提供的主要工具就是partial类,可以用来包装一个有默认参数的callable对象. 得到的对象本身就是callable,可以把它看作是原来的参数. ''' # 举个栗子 def foo(name, age,

Python3标准库:bisect维护有序列表

1. bisect维护有序列表 bisect模块实现了一个算法来向列表中插入元素,同时仍保持列表有序. 1.1 有序插入 下面给出一个简单的例子,这里使用insort()按有序顺序向一个列表中插入元素. import bisect # A series of random numbers values = [14, 85, 77, 26, 50, 45, 66, 79, 10, 3, 84, 77, 1] print('New Pos Contents') print('--- --- ----

Python3标准库:weakref对象的非永久引用

1. weakref对象的非永久引用 weakref模块支持对象的弱引用.正常的引用会增加对象的引用数,并避免它被垃圾回收.但结果并不总是如期望中的那样,比如有时可能会出现一个循环引用,或者有时需要内存时可能要删除对象的缓存.弱引用(weak reference)是一个不能避免对象被自动清理的对象句柄. 1.1 引用 对象的弱引用要通过ref类来管理.要获取原对象,可以调用引用对象. import weakref class ExpensiveObject: def __del__(self):

Python3标准库:hashlib密码散列

1. hashlib密码散列 hashlib模块定义了一个API来访问不同的密码散列算法.要使用一个特定的散列算法,可以用适当的构造器函数或new()来创建一个散列对象.不论使用哪个具体的算法,这些对象都使用相同的API. 1.1 散列算法 由于hashlib有OpenSSL提供“底层支持”,所以OpenSSL库提供的所有算法都可用,包括: md5 sha1 sha224 sha256 sha384 sha512 有些算法在所有平台上都可用,而有些则依赖于底层库.这两种算法分别由algorith