python组成三位无重复数字_Python生成十万个无序且唯一的数字

数字无处不在, 在一些应用场景就特别需要, 比如 订单号 / 防伪码 / 抽奖 / 用户编号 等.

订单号一般都是即时生成的, 比如很多都是用下单时间或者时间戳 如:2020043018010005 或者 1588240860000 还能再加上用户 ID 和随机数, 所以就没什么难度.

但是有些应用场景就不一样了, 比如防伪码和用户编号, 防伪码可能有十万个或者更多, 就需要一次性批量的生成了, 并且还要保证唯一性, 另外因为防伪码的特殊性还需要保证无序. 如果用户编号想做到无序也是一样, 需要先批量生成存储到某个容器, 然后依次拿出使用.

查阅了一些资料, 想了解一下怎么样才能又快又能保证唯一性和无序的大量生成数字, 看到了 "雪花算法", 但是感觉有点难. 劝退了...

博主有简单学一下 Python , 所以就拿 Python 写一下(献丑了)import random

lst_number = []

lst_selected_number = []

start_number = 1000000 # 开始数字

end_number = 9999999 # 结束数字

num = 100000 # 生成数量

if end_number <= start_number:

print('结束数字不能小于开始数字')

exit()

for x in range(start_number, end_number):

lst_number.append(x)

lst_selected_number = random.sample(lst_number, num)

print(lst_selected_number)

将上面代码复制保存到 number.py 并运行. 会打印出一个装满了十万个数字的列表:

watermark

这样一下子就生成出来了十万个无序且唯一的数字.

逻辑很简单, 就是先设置一个空列表, 然后循环遍历开始数字到结束数字, 比如从 1000000 开始, 到 9999999 结束, 将每个遍历出来的数字装入列表, 那么这个列表的元素就有 1000001, 1000002 1000003 ... 直到 9999998. 遍历完成后列表就一共有九百万个数字, 使用 random.sample 函数就能直接从列表的九百万个数字中抽取十万个数字出来, 且是不重复的抽. 所以就拿到了十万个唯一且无序的数字.

拿到数字之后可以保存到一些容器按需使用, 但是仔细看上图, 每个数字的长度都是七位. 假如防伪码需要的是十一位呢, 可以修改代码的开始数字为 10000000000 到 99999999999 然后运行代码会发现, 没反应了... 再打开系统任务管理器, 发现 Python 占用的内存极高.

watermark

再过没多久, 就直接报错了.

watermark

内存不够了...

盲猜是因为遍历存入列表, 列表数据太多把内存撑爆了, 所以使用 Redis 的列表进行存储:import random

import redis

pool = redis.ConnectionPool(host = 'localhost', port = 6379, decode_responses = true)

container_box = redis.Redis(connection_pool = pool) # 连接池

start_number = 10000000000 # 开始数字

end_number = 99999999999 # 结束数字

if end_number <= start_number:

print('结束数字不能小于开始数字')

exit()

for x in range(start_number, end_number):

container_box.lpush("list1", x)

print(container_box.llen("list1"))

执行代码, Redis 会开始存储数字, 使用可视化工具看得很直观

watermark

但是问题来了, 按照之前代码(本文第一段代码)生成九百万个数字的效率, 时间应该是两秒, 第二段代码生成十一位的数字就是九百亿个, 假设一秒能完成九百万个数字, 那也要 10000 秒, 就是最快也要 3 个小时... 但实际肯定是不止的.

博主用了大概两个半小时才生成了七千万个数字就放弃了...

如果已经完成数字遍历并将数字存入了 Redis, 接下来要做的就是按需使用, 需要使用数字的时候, 从 0 到 90000000000 (九百亿) 取一个随机数字, 拿列表中这个随机数字(Key)的元素, 拿取之后记得删除该元素.

经过博主的测试, 生成十万个长度八位(10000000 - 99999999 之间)的数字(无序且唯一)需要用时 17 秒(不使用 Redis)左右.

watermark

九位及以上就爆内存了.. 运行代码的机器是 16G 的. 如果电脑有 32G 或许可以挑战一下11位.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值