我正在练习一些Python而且我无法理解为什么这段代码不会占用 - 函数需要一个字符串,如果它的长度至少为10个字符,则至少有1个数字,1个小写字母和1个大写字母信,它应该返回True。此外,还有一种比我对所有这些嵌套条件更简洁的方式来编写它。谢谢大家!
simplify
答案 0 :(得分:5)
以下内容应该有效,并删除不必要的导入:
def checkio(data):
return len(data) >= 10 and any(char.isdigit() for char in data) and any(char.islower() for char in data) and any(char.isupper() for char in data)
您可以默认迭代字符串,每个字符串都有您可以使用的isdigit,islower等方法。如果传递给它的iterable返回的任何值为true,any()
方法返回True,something(value) for value in iterable
语法创建一个生成器表达式,它迭代字符串的每个字符并检查它是否为a数字/小写/大写字符。
基于this answer。
基准时间,我可怕的基准代码(但似乎可以完成这项工作):
from time import time
import re
data = "ULFFunH8ni" # the password
def benchmark(method): # benchmark method, loops 1000000 times and prints how much it took
start = time()
for _ in range(1000000): method(data)
print(time() - start)
def checkio_kasra(data): # Kasra's answer
return len(data) >= 10 and all([any(i.isdigit() for i in data),any(i.islower() for i in data),any(i.isupper() for i in data)])
def checkio_andreysabitov(data): # Andrey Sabitov's regex-based answer
if len(data) < 10:
return False
digital = re.compile('[0-9]+')
capital = re.compile('[A-Z]+')
lower = re.compile('[a-z]+')
return (digital.search(data) is not None) and (capital.search(data) is not None) and (lower.search(data) is not None)
def checkio_andredaniel(data): # My answer
return len(data) >= 10 and any(char.isdigit() for char in data) and any(char.islower() for char in data) and any(char.isupper() for char in data)
def checkio_shashank_bitmask(data):
if len(data) < 10: return False
lud_bitmask = 0
for ch in data:
if ch.islower():
lud_bitmask |= 4
if lud_bitmask == 7: return True
elif ch.isupper():
lud_bitmask |= 2
if lud_bitmask == 7: return True
elif ch.isdigit():
lud_bitmask |= 1
if lud_bitmask == 7: return True
return False
def checkio_shashank_pure_regex(data):
return bool(re.match(r'(?=.*?[0-9])(?=.*?[A-Z])(?=.*?[a-z]).{10}', data))
def checkio_shashank_impure_regex(data):
return len(data) >= 10 and re.match(r'(?=.*?[0-9])(?=.*?[A-Z])(?=.*?[a-z])', data)
benchmark(checkio_kasra)
benchmark(checkio_andreysabitov)
benchmark(checkio_andredaniel)
benchmark(checkio_shashank_bitmask)
benchmark(checkio_shashank_pure_regex)
benchmark(checkio_shashank_impure_regex)
结果,在我的运行Windows 7和Python 3.4.x的低端平板电脑上运行(运行两次以确定):
$ python pass.py
6.333611011505127 # Shashank
9.625216960906982 # Kasra
11.450419902801514 # Andrey Sabitov
8.36161494255066 # Me
但是,如果1XYZXYZXYZ
的半输入不正确(长度和数字都很好,但都是大写的),某些解决方案无法提前停止:
7.456813097000122 # Shashank
9.328815937042236 # Kasra
11.169620037078857 # Andrey Sabitov
6.349210977554321 # Me
请注意,这些基准测试未考虑最终编辑。我建议你使用最新的答案在自己的机器上运行基准测试。随意用新结果更新这篇文章。
答案 1 :(得分:1)
import re
def checkio(data):
if len(data) < 10:
return False
digital = re.compile('[0-9]+')
capital = re.compile('[A-Z]+')
lower = re.compile('[a-z]+')
return (digital.search(data) is not None) and (capital.search(data) is not None) and (lower.search(data) is not None)
答案 2 :(得分:1)
您可以在any
中使用all
函数的3生成器表达式:
def checkio(data):
return len(data) >= 10 and all([any(i.isdigit() for i in data),any(i.islower() for i in data),any(i.isupper() for i in data)])
演示:
>>> checkio('1&*^&^%%gA')
True
>>> checkio('1&*^&^%%gf')
False
答案 3 :(得分:1)
一种独特的方法是使用bitmask:
def checkio_shashank_bitmask(data):
if len(data) < 10: return False
lud_bitmask = 0
for ch in data:
if ch.islower():
lud_bitmask |= 4
if lud_bitmask == 7: return True
elif ch.isupper():
lud_bitmask |= 2
if lud_bitmask == 7: return True
elif ch.isdigit():
lud_bitmask |= 1
if lud_bitmask == 7: return True
return False
print(checkio('5Hortpass')) # False
print(checkio('dumbpa55w0rd')) # False
print(checkio('DumbPassword')) # False
print(checkio('DumbPassword2015')) # True
这可以很好地适应大型输入和停止。
以下是我认为成为优化的正则表达式解决方案,并且尽快停止非贪婪的积极前瞻:
import re
def checkio_shashank_pure_regex(data):
return bool(re.match(r'(?=.*?[0-9])(?=.*?[A-Z])(?=.*?[a-z]).{10}', data))
但是,我不是正则表达式专家,所以如果你有任何优化想法,请告诉我。
通过一些进一步的测试,我已经确定这个速度要快一点,并且至少对于正确和错误的输入而言,这可能是迄今为止最快的解决方案,至少使用高度优化的正则表达式模块:
def checkio_shashank_impure_regex(data):
return len(data) >= 10 and re.match(r'(?=.*?[0-9])(?=.*?[A-Z])(?=.*?[a-z])', data)
答案 4 :(得分:0)
我发现这个功能既有效又美观。
def check(password):
"""Returns True only if password is strong enough."""
if (len(password) >= 10
and any(char.isdigit() for char in password)
and any(char.islower() for char in password)
and any(char.isupper() for char in password)):
return True
else:
return False
答案 5 :(得分:0)
r_p = re.compile('^(?=\S{6,20}$)(?=.*?\d)(?=.*?[a-z])(?=.*?[A-Z])(?=.*?[^A-Za-z\s0-9])')
此代码将使用以下命令验证您的密码:
答案 6 :(得分:-1)
如果len
条件为false,则代码仅执行else语句。解决这个问题:
更紧凑的版本,你可以这样做:
if len(data) >= 10 and any(i in data for i in digs) and (i in data for i in alphaupper) and (i in data for i in alphalower):