You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何我的两款近似Python密码生成算法运行速度相差近10倍?

为什么第二段密码生成代码运行速度远快于第一段?

我是编程新手,任务是生成指定数量和长度的密码。第一段代码可以运行,但速度极慢(测试时甚至无法得到结果),修改后的第二段代码运行速度飞快,想知道背后的原因。

第一段代码(运行极慢)

from random import choices, choice


def generate_password(m):
    ch = choices('23456789qwertyupasdfghjkzxcvbnmiLQWERTYUPASDFGHJKZXCVBNM', k=m - 3)
    ch.append(choice('LQWERTYUPASDFGHJKZXCVBNM'))
    ch.append(choice('qwertyupasdfghjkzxcvbnmi'))
    ch.append(choice('23456789'))
    return ''.join(ch)


def main(n, m):
    p = set()
    t = 0
    while t < n:
        s = generate_password(m)
        if s not in p:
            t += 1
            p.add(s)
    return p

测试情况

使用以下测试代码(参数为生成4609个长度3的密码),始终无法得到结果:

from time import time
from random import choices, choice


def generate_password(m):
    ch = choices('23456789qwertyupasdfghjkzxcvbnmiLQWERTYUPASDFGHJKZXCVBNM', k=m - 3)
    ch.append(choice('LQWERTYUPASDFGHJKZXCVBNM'))
    ch.append(choice('qwertyupasdfghjkzxcvbnmi'))
    ch.append(choice('23456789'))
    return ''.join(ch)


def main(n, m):
    p = set()
    t = 0
    while t < n:
        s = generate_password(m)
        if s not in p:
            t += 1
            p.add(s)
    return p


t1 = time()
print(*main(4609, 3))
t2 = time()
print(t2 - t1)

第二段代码(运行飞快)

from random import choices, shuffle, choice


def generate_password(m):
    global p
    ch = choices('LQWERTYUPASDFGHJKZXCVBNM', k=m - 3)
    ch.append(choice('LQWERTYUPASDFGHJKZXCVBNM'))
    ch.append(choice('qwertyupasdfghjkzxcvbnmi'))
    ch.append(choice('23456789'))
    while True:
        tt = ''.join(ch)
        if tt in p:
            shuffle(ch)
            continue
        return tt


p = set()


def main(n, m):
    global p
    t = 0
    while t < n:
        p.add(generate_password(m))
        t += 1
    return p

测试情况

使用以下测试代码,输出耗时仅0.05657219886779785:

from time import time
from random import choices, shuffle, choice


def generate_password(m):
    global p
    ch = choices('LQWERTYUPASDFGHJKZXCVBNM', k=m - 3)
    ch.append(choice('LQWERTYUPASDFGHJKZXCVBNM'))
    ch.append(choice('qwertyupasdfghjkzxcvbnmi'))
    ch.append(choice('23456789'))
    while True:
        tt = ''.join(ch)
        if tt in p:
            shuffle(ch)
            continue
        return tt


p = set()


def main(n, m):
    global p
    t = 0
    while t < n:
        p.add(generate_password(m))
        t += 1
    return p


t1 = time()
print(*main(4609, 3))
t2 = time()
print(t2 - t1)

原因解析

核心原因不是shuffle()比choice()高效,而是两段代码的密码生成逻辑存在本质差异,尤其是在m=3的测试场景下:

  1. 第一段代码的致命问题
    当m=3时,m-3=0,choices生成空列表,后续追加的三个字符固定为「大写字母+小写字母+数字」的顺序。这种固定顺序的组合总数为:23个大写 × 23个小写 × 8个数字 = 4232种唯一密码。但你需要生成4609个,已经超过了所有可能的唯一密码数。
    这导致第一段代码的while t < n循环会陷入死循环:当所有4232种密码都被加入集合后,后续生成的全是重复值,t再也无法增长,永远达不到n=4609,所以你永远等不到结果。

  2. 第二段代码的逻辑优势
    同样当m=3时,初始生成的字符还是「大写+小写+数字」,但代码会通过shuffle()打乱这三个字符的顺序,直到得到不在集合中的组合。这使得密码的可能组合扩展为这三个字符的所有排列(共3! = 6种),总唯一密码数变为4232 × 6 = 25392种,远大于需求的4609个。
    因此程序可以快速生成足够的唯一密码,不会陷入死循环,这才是速度快的核心原因。

  3. 额外补充
    第一段代码的逻辑设计本身就有缺陷:强制固定字符类型的位置,极大限制了唯一密码的总数,当需求数量超过这个总数时必然死循环。第二段代码通过打乱顺序扩展了密码空间,从根本上解决了这个问题。

内容的提问来源于stack exchange,提问作者Father Sergey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 02:05:34