我怎样才能使这个 Python 代码更有效率
How can I make this Python code more efficient
非常感谢您对我的第一个 Python 项目的反馈! :D
基本上我正在编写凯撒密码,我认为它非常可怕 'optimised / efficient' 如果你明白我的意思,这是因为我复制并粘贴了用于 decrypt() 方法的 encrypt() 方法和我唯一改变的是不是更多地旋转数字,而是更少地旋转它们。这就是我要说的:
newPosition = (abc.find(letter) - key) % 26
^^ Instead of having a + (plus) I made it a - (minus) ^^
有没有一种方法可以仅在 newPosition 行调用 encrypt() 方法?或者我做的是正确的,不需要修复(我非常怀疑)
** 请记住,我对 Python 了解不多(如果有的话),因为我今天才刚开始,所以不要用一些超级复杂的代码来破坏我的大脑。谢谢你!!! **
abc = 'abcdefghijklmnopqrstuvwxyz'
def main():
message = input("Would you like to encrypt or decrypt a word?")
if message.lower() == "encrypt":
encrypt()
elif message.lower() == "decrypt":
decrypt()
else:
print("You must enter either 'encrypt' or 'decrypt'.")
main()
def encrypt():
message = input("Enter a message to encrypt: ")
message = message.lower()
key = int(input("What number would you like for your key value?"))
cipherText = ""
for letter in message:
if letter in abc:
newPosition = (abc.find(letter) + key) % 26
cipherText += abc[newPosition]
else:
cipherText += letter
print(cipherText)
return cipherText
def decrypt():
message = input("Enter a message to decrypt: ")
message = message.lower()
key = int(input("What number would you like for your key value?"))
cipherText = ""
for letter in message:
if letter in abc:
newPosition = (abc.find(letter) - key) % 26
cipherText += abc[newPosition]
else:
cipherText += letter
print(cipherText)
return cipherText
main()
一般来说,str.find
的性能很差。它是 O(n) 复杂度,这并不可怕,但您实际上很少需要它。在这种情况下,您可以使用 ord
将每个字母转换为其序数,然后减去 ord('a')
得到 0-25 而不是 97-122。
这特别有用,因为您可以使用 chr
转换回来而无需查找。
for letter in message:
if letter in string.ascii_lowercase: # same as "abcdef..z"
new_position = ((ord(letter) - ord('a') + key) % 26) + ord('a')
new_ch = chr(new_position)
ciphertext += new_ch
另请注意,使用 +=
连接字符串的速度不如 str.join
.
new_letters = [chr(((ord(letter) - ord('a') + key) % 26) + ord('a')) if letter in ascii_lowercase else letter for letter in message]
ciphertext = "".join(new_letters)
因为 chr(((ord(letter) - ord('a') + key) % 26) + ord('a'))
太丑了,我会把它重构为一个函数。
def rotate(letter, key=0):
c_pos = ord(letter) - ord('a')
rotated = c_pos + key
modded = rotated % 26
final_pos = modded + ord('a')
return chr(final_pos)
new_letters = [rotate(c, key) if c in string.ascii_lowercase else c for c in letters]
ciphertext = "".join(new_letters)
可维护性要点:如果将输入与结果分开,编写 可测试 好的代码会更容易。现在您必须对 stdin
进行一些猴子修补才能为您的任何函数编写单元测试,但是如果您将用户输入请求移入 main
并移出它们各自的函数,那变得容易多了。
def main():
message = input("What's the message to encrypt/decrypt? ")
key = int(input("What number would you like for your key value? "))
choice = input("Choose: encrypt or decrypt. ")
if choice == "encrypt":
result = encrypt(message, key)
elif choice == "decrypt":
result = decrypt(message, key)
else:
# something here about a bad user input.
事实上,当你认为凯撒密码是翻转密钥符号可逆时,你可以简单地做:
if choice == "encrypt":
result = encrypt(message, key)
elif choice == "decrypt":
result = encrypt(message, key * (-1))
并且根本不写 decrypt
函数!
非常感谢您对我的第一个 Python 项目的反馈! :D
基本上我正在编写凯撒密码,我认为它非常可怕 'optimised / efficient' 如果你明白我的意思,这是因为我复制并粘贴了用于 decrypt() 方法的 encrypt() 方法和我唯一改变的是不是更多地旋转数字,而是更少地旋转它们。这就是我要说的:
newPosition = (abc.find(letter) - key) % 26
^^ Instead of having a + (plus) I made it a - (minus) ^^
有没有一种方法可以仅在 newPosition 行调用 encrypt() 方法?或者我做的是正确的,不需要修复(我非常怀疑)
** 请记住,我对 Python 了解不多(如果有的话),因为我今天才刚开始,所以不要用一些超级复杂的代码来破坏我的大脑。谢谢你!!! **
abc = 'abcdefghijklmnopqrstuvwxyz'
def main():
message = input("Would you like to encrypt or decrypt a word?")
if message.lower() == "encrypt":
encrypt()
elif message.lower() == "decrypt":
decrypt()
else:
print("You must enter either 'encrypt' or 'decrypt'.")
main()
def encrypt():
message = input("Enter a message to encrypt: ")
message = message.lower()
key = int(input("What number would you like for your key value?"))
cipherText = ""
for letter in message:
if letter in abc:
newPosition = (abc.find(letter) + key) % 26
cipherText += abc[newPosition]
else:
cipherText += letter
print(cipherText)
return cipherText
def decrypt():
message = input("Enter a message to decrypt: ")
message = message.lower()
key = int(input("What number would you like for your key value?"))
cipherText = ""
for letter in message:
if letter in abc:
newPosition = (abc.find(letter) - key) % 26
cipherText += abc[newPosition]
else:
cipherText += letter
print(cipherText)
return cipherText
main()
一般来说,str.find
的性能很差。它是 O(n) 复杂度,这并不可怕,但您实际上很少需要它。在这种情况下,您可以使用 ord
将每个字母转换为其序数,然后减去 ord('a')
得到 0-25 而不是 97-122。
这特别有用,因为您可以使用 chr
转换回来而无需查找。
for letter in message:
if letter in string.ascii_lowercase: # same as "abcdef..z"
new_position = ((ord(letter) - ord('a') + key) % 26) + ord('a')
new_ch = chr(new_position)
ciphertext += new_ch
另请注意,使用 +=
连接字符串的速度不如 str.join
.
new_letters = [chr(((ord(letter) - ord('a') + key) % 26) + ord('a')) if letter in ascii_lowercase else letter for letter in message]
ciphertext = "".join(new_letters)
因为 chr(((ord(letter) - ord('a') + key) % 26) + ord('a'))
太丑了,我会把它重构为一个函数。
def rotate(letter, key=0):
c_pos = ord(letter) - ord('a')
rotated = c_pos + key
modded = rotated % 26
final_pos = modded + ord('a')
return chr(final_pos)
new_letters = [rotate(c, key) if c in string.ascii_lowercase else c for c in letters]
ciphertext = "".join(new_letters)
可维护性要点:如果将输入与结果分开,编写 可测试 好的代码会更容易。现在您必须对 stdin
进行一些猴子修补才能为您的任何函数编写单元测试,但是如果您将用户输入请求移入 main
并移出它们各自的函数,那变得容易多了。
def main():
message = input("What's the message to encrypt/decrypt? ")
key = int(input("What number would you like for your key value? "))
choice = input("Choose: encrypt or decrypt. ")
if choice == "encrypt":
result = encrypt(message, key)
elif choice == "decrypt":
result = decrypt(message, key)
else:
# something here about a bad user input.
事实上,当你认为凯撒密码是翻转密钥符号可逆时,你可以简单地做:
if choice == "encrypt":
result = encrypt(message, key)
elif choice == "decrypt":
result = encrypt(message, key * (-1))
并且根本不写 decrypt
函数!