random.choice() returns 同一秒相同的值,如何避免呢?
random.choice() returns same value at the same second, how does one avoid it?
我一直在寻找有关如何在 python 中生成随机数的类似问题。示例:Similar Question - 但我没有遇到随机函数 returns 每次都具有相同值的问题。
我的随机生成器工作正常,问题是它 returns 调用函数时的值相同,我认为是同一秒,这是不希望的。
我的代码如下所示
def getRandomID():
token = ''
letters = "abcdefghiklmnopqrstuvwwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
for i in range(1,36):
token = token + random.choice(letters)
return token
正如我提到的,此函数在不同时间调用时 returns 不同的值,但同时调用该函数时 returns 相同的值。我该如何避免这个问题?
我在后端服务器中使用此功能为前端用户生成唯一 ID 以插入数据库,因此我无法控制发生这种情况的时间间隔。我必须有随机标记来映射数据库中的用户,以便能够使用数据库中的 queuenumbers 正确插入它们。
您可以使用 random.SystemRandom()
来改善问题,如下所示:
import random
sys_random = random.SystemRandom()
def getRandomID():
token = ''
letters = "abcdefghiklmnopqrstuvwwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
for i in range(1, 36):
token = token + sys_random.choice(letters)
return token
print(getRandomID())
这尝试使用 os.urandom()
函数,该函数从操作系统提供的源中生成随机数。 .choices()
函数也可用于在一次调用中 return 选择列表,避免字符串连接:
import random
sys_random = random.SystemRandom()
def getRandomID():
letters = "abcdefghiklmnopqrstuvwwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
return ''.join(sys_random.choices(letters, k=35))
print(getRandomID())
def getRandomID(n):
import datetime
import random
random.seed(datetime.datetime.now())
letters = "abcdefghiklmnopqrstuvwwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
idList = [ ''.join([random.choice(letters) for j in range(1,36)]) for i in range(n)]
return idList
这个脚本在第三次1000万个id的测试中再次使它们都是唯一的
将 for 循环更改为列表理解确实加快了很多速度。
>>> listt = getRandomID(10000000)
>>> print(len(listt))
10000000
>>> setOfIds = set(listt)
>>> print(len(setOfIds))
10000000
此脚本使用重复排列:62 选择 35,
理论上 id 的总数相当大,它是 pow(62,35)
541638008296341754635824011376225346986572413939634062667808768
另一种选择是用先前的结果更新种子以获得伪随机序列。一个选项是 old_seed XOR 结果或只是结果。
我一直在寻找有关如何在 python 中生成随机数的类似问题。示例:Similar Question - 但我没有遇到随机函数 returns 每次都具有相同值的问题。
我的随机生成器工作正常,问题是它 returns 调用函数时的值相同,我认为是同一秒,这是不希望的。
我的代码如下所示
def getRandomID():
token = ''
letters = "abcdefghiklmnopqrstuvwwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
for i in range(1,36):
token = token + random.choice(letters)
return token
正如我提到的,此函数在不同时间调用时 returns 不同的值,但同时调用该函数时 returns 相同的值。我该如何避免这个问题?
我在后端服务器中使用此功能为前端用户生成唯一 ID 以插入数据库,因此我无法控制发生这种情况的时间间隔。我必须有随机标记来映射数据库中的用户,以便能够使用数据库中的 queuenumbers 正确插入它们。
您可以使用 random.SystemRandom()
来改善问题,如下所示:
import random
sys_random = random.SystemRandom()
def getRandomID():
token = ''
letters = "abcdefghiklmnopqrstuvwwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
for i in range(1, 36):
token = token + sys_random.choice(letters)
return token
print(getRandomID())
这尝试使用 os.urandom()
函数,该函数从操作系统提供的源中生成随机数。 .choices()
函数也可用于在一次调用中 return 选择列表,避免字符串连接:
import random
sys_random = random.SystemRandom()
def getRandomID():
letters = "abcdefghiklmnopqrstuvwwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
return ''.join(sys_random.choices(letters, k=35))
print(getRandomID())
def getRandomID(n):
import datetime
import random
random.seed(datetime.datetime.now())
letters = "abcdefghiklmnopqrstuvwwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
idList = [ ''.join([random.choice(letters) for j in range(1,36)]) for i in range(n)]
return idList
这个脚本在第三次1000万个id的测试中再次使它们都是唯一的
将 for 循环更改为列表理解确实加快了很多速度。
>>> listt = getRandomID(10000000)
>>> print(len(listt))
10000000
>>> setOfIds = set(listt)
>>> print(len(setOfIds))
10000000
此脚本使用重复排列:62 选择 35, 理论上 id 的总数相当大,它是 pow(62,35)
541638008296341754635824011376225346986572413939634062667808768
另一种选择是用先前的结果更新种子以获得伪随机序列。一个选项是 old_seed XOR 结果或只是结果。