python - 如何缩短这个 bool 表达式?

标签 python python-3.x

我是制作密码生成器的初学者,需要确保密码同时包含数字和大写字母。这个 while 循环的条件是多余的。 for char in password 出现两次。你会怎么写?

while not (any(char.isdigit() for char in password) and (any(char.isupper() for 
char in password))):

在循环中它生成另一个密码。

我的目标是更好地理解如何构造 while 循环的表达式,而不是用不同的方式解决问题。

最佳答案

首先,我希望网站停止对空洞的密码要求。它们降低了密码的熵并使人们更难记住。如果要求没有在 UI 中明确列出,这样人们就可以设计一个合适的密码,而无需猜测您可能为他们设置的陷阱,这尤其糟糕。

也就是说,您的语法比某些正则表达式实现要短得多。如果您想应用德摩根定律将问题分解成可以说更容易推理的逻辑,您可以执行以下操作(在短路方面有性能损失)。

while all(not char.isdigit() for char in password)
       or all(not char.isupper() for char in password):

看来你真正的问题是两次通过 password。有趣的是,正则表达式方法有同样的问题,隐藏在一些额外的语法后面。如果您愿意为了通用性、短路能力和一次通过数据而牺牲解决方案的简洁性,那么您可以像这样将条件提取到它自己的方法中:

def satisfies(password, *conditions):
    flags = [False] * len(conditions)
    for c in password:
        for i, cond in enumerate(conditions):
            if cond(c):
                flags[i] = True
                if all(flags):
                    return True
    return False

while satisfies(password, str.isdigit, str.isupper):
    pass

逐步执行此过程,它会遍历每个字符和每个条件(例如需要数字的条件)并检查是否已满足。如果是这样,它会记录该事件并检查它是否可以提前退出。最后,for 循环退出的唯一可能方式是如果 password 中的任何地方都没有满足条件,所以我们返回 False.

只是为了好玩,您可以使用 reduce() 函数获得类似的效果(无需提前停止)。它内置于 Python 2.x 中,您需要从 Python 3.x 中的 functools 导入它。

while not all(reduce(
        lambda (a, b), (d, e): (a or d, b or e),
        ((c.isdigit(), c.isupper()) for c in password))):

这有效地记录了您是否满足密码中的 isdigit 和 isupper 要求。检查整个密码后,您只需使用 all() 来读取您的记录并确保您确实满足了这两个要求。

如果您的目标是运行时间而不是像“传递数据”这样的空灵概念(不是贬低;它们在其他情况下可能很重要),那么您最好的改进将来自某种高性能numpy 之类的库旨在对您执行的查询进行矢量化。由于此处执行的大部分工作不是遍历数据,而是每次遍历中对字符执行的检查,因此消除遍历数据对运行时间不会有太大帮助。通过尽快进行实际检查,您将实现最大的节省。

关于python - 如何缩短这个 bool 表达式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51870069/

相关文章:

python - 使用 __pycache__ 时 pytest 会隐藏警告

python - 如何导入相互导入的文件?

python-3.x - 将日志记录与彩色日志一起使用

python - python - 如何在python中断言一个字典包含另一个没有assertDictContainsSubset的字典?

python - 使用 webdriver 滚动到元素?

python - 将元组数组构建为元素

python - 如何在没有着色器的情况下将 glDrawArrays 与纹理数组一起使用

python - 如何创建 .desktop 文件以在 Linux 上启动 python 脚本?

python - 我的代码有时会给出错误的输出,如何解决?

python - 为什么 NotImplemented 不引发 TypeError?