比堆叠 try 和 except 更好的测试列表中值的方法
Better way to test for a value in a list than to stack try's and except's
我的代码正在实现凯撒密码,这个函数应该将输入的字符串转换为加密的字符串。
为此,我必须在 2 个列表中搜索字符,一个小写字母列表,一个大写字母列表,然后如果不是字母,只需将字符添加到加密字符串中即可。
我决定使用两层 try 和 except 来做到这一点。有没有更好的方法可以做到这一点,也许 if/else?
import string
from tkinter import *
from tkinter import ttk
alphaLower = string.ascii_lowercase
alphaUpper = string.ascii_uppercase
alphaShiftL = alphaLower
alphaShiftU = alphaUpper
def shiftList(amount):
global alphaShiftL
global alphaShiftU
alphaShiftL = alphaLower[amount:] + alphaShiftL[:amount]
alphaShiftU = alphaUpper[amount:] + alphaShiftU[:amount]
def encrypt(unencrypted):
encrypted = ''
for char in unencrypted:
#HERE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
try:
alphaLower.index(char)
encrypted += alphaShiftL[alphaLower.index(char)]
except ValueError:
try:
encrypted += alphaShiftU[alphaUpper.index(char)]
except ValueError:
encrypted += char
return encrypted
如果我没理解错的话,你只需要知道列表中是否存在某些内容。您可以使用以下方法测试集合包含:
if search in collection:
ix = collection.index(search)
else:
//handle no
我的理解正确吗?
编辑:mgilson 的解决方案,因为您需要元素的索引。
ix = collection.find(search)
if ix != -1:
//handle yes
else:
//handle no
if char.islower():
encrypted += alphaShiftL[alphaLower.index(char)]
elif char.isupper():
encrypted += alphaShiftU[alphaUpper.index(char)]
else:
encrypted += char
有更有效的方法来实现这一点——但是使用你所拥有的,我可能建议的第一件事是连接列表,这样你只需要 1 try/except:
alpha = alphaLower + alphaUpper
alphaShift = alphaShiftL + alphaShiftU
for char in unencrypted:
try:
encrypted += alphaShift[alpha.index(char)]
except ValueError:
encrypted += char
现在我们只有一个 try/except 这很好。
如果我们继续只使用包含 映射 的单个对象,我们可以做得更好——更好得多。在这种情况下,您真正想要做的是将 alpha 中的一个字符映射到 alphaShift 中的另一个字符。我们可以用 python dict:
简单地做到这一点
mapping = dict(zip(alpha, alphaShift))
for char in unencrypted:
encrypted += mapping.get(char, char)
或者,更有效:
mapping = dict(zip(alpha, alphaShift))
encrypted = ''.join(mapping.get(char, char) for char in unencrypted)
到"decrypt",你只需要逆映射:
inverse_mapping = dict(zip(alphaShift, alpha))
unencrypted = ''.join(inverse_mapping.get(char, char) for char in encrypted)
除非这是一个学术练习,否则我不明白你为什么要这样组织你的代码。如果您热衷于将信息保存在数组中,那么您可以将它们连接在一起,这样您只需一次查找即可。
alphaLower = string.ascii_lowercase
alphaUpper = string.ascii_uppercase
alpha = alphaLower + alphaUpper
alphaShift = alpha
def shiftList(amount):
global alphaShiftL
global alphaShiftU
alphaShiftL = alphaLower[amount:] + alphaShiftL[:amount]
alphaShiftU = alphaUpper[amount:] + alphaShiftU[:amount]
alphaShift = alphaShiftL + alphaShiftU
现在您可以直接进行查找:
def encrypt(unencrypted):
encrypted = ''
for char in unencrypted:
idx = alpha.find(char)
encrypted += alphaShift[idx] if idx >= 0 else char
return encrypted
但是,只使用字典会好得多:
lc = string.ascii_lowercase
uc = string.ascii_uppercase
cipher = dict(zip(lc+uc, lc[13:]+lc[:13]+uc[13:]+uc[:13]))
def encrypt(input):
return ''.join(cipher.get(c,c) for c in input)
我的代码正在实现凯撒密码,这个函数应该将输入的字符串转换为加密的字符串。
为此,我必须在 2 个列表中搜索字符,一个小写字母列表,一个大写字母列表,然后如果不是字母,只需将字符添加到加密字符串中即可。
我决定使用两层 try 和 except 来做到这一点。有没有更好的方法可以做到这一点,也许 if/else?
import string
from tkinter import *
from tkinter import ttk
alphaLower = string.ascii_lowercase
alphaUpper = string.ascii_uppercase
alphaShiftL = alphaLower
alphaShiftU = alphaUpper
def shiftList(amount):
global alphaShiftL
global alphaShiftU
alphaShiftL = alphaLower[amount:] + alphaShiftL[:amount]
alphaShiftU = alphaUpper[amount:] + alphaShiftU[:amount]
def encrypt(unencrypted):
encrypted = ''
for char in unencrypted:
#HERE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
try:
alphaLower.index(char)
encrypted += alphaShiftL[alphaLower.index(char)]
except ValueError:
try:
encrypted += alphaShiftU[alphaUpper.index(char)]
except ValueError:
encrypted += char
return encrypted
如果我没理解错的话,你只需要知道列表中是否存在某些内容。您可以使用以下方法测试集合包含:
if search in collection:
ix = collection.index(search)
else:
//handle no
我的理解正确吗?
编辑:mgilson 的解决方案,因为您需要元素的索引。
ix = collection.find(search)
if ix != -1:
//handle yes
else:
//handle no
if char.islower():
encrypted += alphaShiftL[alphaLower.index(char)]
elif char.isupper():
encrypted += alphaShiftU[alphaUpper.index(char)]
else:
encrypted += char
有更有效的方法来实现这一点——但是使用你所拥有的,我可能建议的第一件事是连接列表,这样你只需要 1 try/except:
alpha = alphaLower + alphaUpper
alphaShift = alphaShiftL + alphaShiftU
for char in unencrypted:
try:
encrypted += alphaShift[alpha.index(char)]
except ValueError:
encrypted += char
现在我们只有一个 try/except 这很好。
如果我们继续只使用包含 映射 的单个对象,我们可以做得更好——更好得多。在这种情况下,您真正想要做的是将 alpha 中的一个字符映射到 alphaShift 中的另一个字符。我们可以用 python dict:
简单地做到这一点mapping = dict(zip(alpha, alphaShift))
for char in unencrypted:
encrypted += mapping.get(char, char)
或者,更有效:
mapping = dict(zip(alpha, alphaShift))
encrypted = ''.join(mapping.get(char, char) for char in unencrypted)
到"decrypt",你只需要逆映射:
inverse_mapping = dict(zip(alphaShift, alpha))
unencrypted = ''.join(inverse_mapping.get(char, char) for char in encrypted)
除非这是一个学术练习,否则我不明白你为什么要这样组织你的代码。如果您热衷于将信息保存在数组中,那么您可以将它们连接在一起,这样您只需一次查找即可。
alphaLower = string.ascii_lowercase
alphaUpper = string.ascii_uppercase
alpha = alphaLower + alphaUpper
alphaShift = alpha
def shiftList(amount):
global alphaShiftL
global alphaShiftU
alphaShiftL = alphaLower[amount:] + alphaShiftL[:amount]
alphaShiftU = alphaUpper[amount:] + alphaShiftU[:amount]
alphaShift = alphaShiftL + alphaShiftU
现在您可以直接进行查找:
def encrypt(unencrypted):
encrypted = ''
for char in unencrypted:
idx = alpha.find(char)
encrypted += alphaShift[idx] if idx >= 0 else char
return encrypted
但是,只使用字典会好得多:
lc = string.ascii_lowercase
uc = string.ascii_uppercase
cipher = dict(zip(lc+uc, lc[13:]+lc[:13]+uc[13:]+uc[:13]))
def encrypt(input):
return ''.join(cipher.get(c,c) for c in input)