我创建了一个生成字符串迭代的程序。但是,我无法打印总数。这是我的代码: 来自itertools导入产品 for commonpasswords中的密码: password = password.strip('\ n')
基本上我只想要1个数字来突变总数。感谢。
如果你可以帮助我的话,我也会得到一个KeyError'\ r'。
编辑:这是我得到的错误:
Traceback (most recent call last):
File "test.py", line 17, in <module>
allPossible = list(product(*([letter] + mapping[letter] for letter in password)))
File "test.py", line 17, in <genexpr>
allPossible = list(product(*([letter] + mapping[letter] for letter in password)))
KeyError: '\r'
答案 0 :(得分:0)
要摆脱KeyError \r
,请password.strip('\n')
跟password.strip('\r')
这意味着您正试图在mapping
词典中查找不存在的值
在这一行
allPossible = list(product(*([letter] + mapping[letter] for letter in password)))
for letter in password
逐个浏览这些字母,然后在mapping
mapping[letter]
中查找可能的替代字。与任何字典一样,如果letter
不是mapping
中的密钥,则会出现KeyError。
您需要决定如何处理不在字典中的字符。你可以做一些事情
try
块中,然后使用except
捕获错误。这会从结果中省略该密码,但允许您的代码继续运行\n
和\r
一样),直到您确定只在地图中留下字符'_':['_']
添加为mapping
的条目)mapping
字典中的值。修复后,您的代码会输出文件的运行总数突变 - 逐个添加每行的突变
如果您只想在结尾处打印(即文件总数),请从print(total)
行中删除缩进。
您可能误解了python缩进结构 - for
或while
后面的每个缩进行将在每个循环中运行一次。您不希望在每个循环上执行print
语句,因此请删除缩进。
答案 1 :(得分:0)
将代码分解为函数可以使理解和重用更容易
您可以使用dict.get
为不在字典中的项目提供默认值;
v = count.get(ch, 1)
相当于
try:
v = count[ch]
except KeyError:
v = 1
您可以通过乘以每个字母的替代数量来计算变体的数量;这比实际生成所有可能性并计算它们的速度快 。
您可以使用word.strip()
代替word.strip("\n").strip("\r")
;它删除任何前导或尾随制表符或空格字符,但这是无关紧要的,因为它们没有映射,因此不会影响最终总数。
所以,
mapping = {
'a': ['A', '@'], 'b': ['B', '8'], 'c': ['C', '('],
'd': ['D'], 'e': ['E', '3'], 'f': ['F'],
'g': ['G'], 'h': ['H'], 'i': ['I', '1'],
'j': ['J'], 'k': ['K'], 'l': ['L'],
'm': ['M'], 'n': ['N'], 'o': ['O', '0'],
'p': ['P'], 'q': ['Q'], 'r': ['R'],
's': ['S'], 't': ['T', '7'], 'u': ['U'],
'v': ['V'], 'w': ['W'], 'x': ['X'],
'y': ['Y'], 'z': ['Z'], '1': ['i', 'I'],
'2': ['2'], '3': ['e', 'E'], '4': ['H', 'h'],
'5': ['s', 'S'], '6': ['b'], '7': ['L', 'l'],
'8': ['B'], '9': ['9'], '0': ['o', '0']
}
# precalculate number of variants for each letter
count = {ch:len(lst)+1 for ch,lst in mapping.items()}
def variants(word):
"""
Return the number of variations possible
by replacing some letters in `word` with
their alternatives from `mapping`
"""
p = 1
for ch in word:
p *= count.get(ch, 1)
return p
def total_variants(wordlist):
return sum(variants(word) for word in wordlist)
def main():
with open("commonpasswords.txt") as inf:
print(total_variants(line.strip() for line in inf))
if __name__ == "__main__":
main()