第12行的for循环和嵌套在其中的for循环,我的意思是。我不止一次遇到过这样的情况。我使用列表理解,但它似乎不会在这里工作。
import random
import string
def password_generator():
key = zip(string.digits, string.ascii_uppercase)
cruft, x = str(random.random()).split('.')
pw = ''
for item in x:
for element in key:
if item in element:
Q = random.random()
if Q > 0.7:
pw += element[1].lower()
else:
pw += element[1]
print pw
感谢。
答案 0 :(得分:3)
这是一种使用列表理解的方法:
def pw_gen():
key = zip(string.digits, string.ascii_uppercase)
cruft, x = str(random.random()).split('.')
def f(i,e):
Q = random.random()
if Q > 0.7:
return e[1].lower()
else:
return e[1]
return [ f(item,element) for item in x for element in key if item in element ]
返回一个字符列表。使用"".join( pw_gen() )
转换为字符串。
答案 1 :(得分:2)
我认为让你难以做到这一点的原因是你在循环中间得到了random.random()< 0.7部分。使它成为一个单独的函数,并且更容易将其转换为列表理解。
def f(str):
if random.random()>0.7:
return str.lower()
else:
return str
''.join([f(element[1]) for element in key for item in x if item in element])
答案 2 :(得分:2)
您可以使用itertools.product将这两者结合起来,但我觉得使用随机的更高级别方法可以简化此任务。
symbols=string.ascii_uppercase[:10]
pw = ''
for i in range(15):
letter = random.choice(symbols)
if random.random() > 0.7:
letter = letter.lower()
pw += letter
甚至更短:
symbols = (7*string.ascii_uppercase[:10] +
3*string.ascii_lowercase[:10])
pw = ''.join(random.choice(symbols) for i in range(15))
您构建key
的方式使其成为效率非常低的查找表。您可以替换几行以使用更有效的方法:
key = dict(zip(string.digits, string.ascii_uppercase))
#...
for item in x:
letter = key[item]
不可否认,这些都会产生一个固定长度的密码,而你的字符串转换很少有机会获得更短的密码。但是,出于类似的原因,最后一位数字的随机性不如其他数字。
答案 3 :(得分:0)
与使用列表推导替换内部for循环相比,您的逻辑可以大大简化。这将等同于您的代码:
import random
import string
key = dict(zip(string.digits, string.ascii_uppercase))
cruft, x = str(random.random()).split('.', 1)
pw = ''
for item in x:
if item in key: # This if is not required as all the single digits are present
Q = random.random()
if Q>0.7:
pw += key[item].lower()
else:
pw += key[item]
print pw
但是,如果您确实希望密码是唯一的,并且不需要轻松进行逆向工程,我建议您使用UUID。如果您想要一个更好的密码生成器(带有字母数字和符号),您可以执行this之类的操作。
请注意,它不是官方的python网站,也可以通过多种方式进行改进。像往常一样,我的意思是to shoot,以任何方式使用它。