Python 更高效的代码(似乎有太多的if语句)
我已经调查过了,但是我找不到任何对我有帮助的东西(如果类似的问题的答案可能对我有帮助,我表示歉意)。我正在编写一个货币转换器,它遭受大量的Python 更高效的代码(似乎有太多的if语句),python,python-3.x,if-statement,optimization,Python,Python 3.x,If Statement,Optimization,我已经调查过了,但是我找不到任何对我有帮助的东西(如果类似的问题的答案可能对我有帮助,我表示歉意)。我正在编写一个货币转换器,它遭受大量的,如果看起来效率不高,也无法想象可读性很好,那么我想知道如何在这种情况下编写更高效的代码: prompt = input("Input") #For currency, inputs should be written like "C(NUMBER)(CURRENCY TO CONVERT FROM)(CURRENCY TO CONVERT TO)" exam
,如果看起来效率不高,也无法想象可读性很好,那么我想知道如何在这种情况下编写更高效的代码:
prompt = input("Input") #For currency, inputs should be written like "C(NUMBER)(CURRENCY TO CONVERT FROM)(CURRENCY TO CONVERT TO)" example "C1CPSP"
if prompt[0] == "C": #Looks at first letter and sees if it's "C". C = Currency Conversion
#CP = Copper Piece, SP = Silver Piece, EP = Electrum Piece, GP = Gold Piece, PP = Platinum Piece
ccint = int(''.join(list(filter(str.isdigit, prompt)))) # Converts Prompt to integer(Return string joined by str.(Filters out parameter(Gets digits (?), from prompt))))
ccalpha = str(''.join(list(filter(str.isalpha, prompt)))) #Does the same thing as above expect with letters
if ccalpha[1] == "C": #C as in start of CP
acp = [ccint, ccint/10, ccint/50, ccint/100, ccint/1000] #Array of conversions. CP, SP, EP, GP, PP
if ccalpha[3] == "C": #C as in start of CP
print(acp[0]) #Prints out corresponding array conversion
if ccalpha[3] == "S": #S as in start of SP, ETC. ETC.
print(acp[1])
if ccalpha[3] == "E":
print(acp[2])
if ccalpha[3] == "G":
print(acp[3])
if ccalpha[3] == "P":
print(acp[4])
if ccalpha[1] == "S":
asp = [ccint*10, ccint, ccint/10, ccint/10, ccint/100]
if ccalpha[3] == "C":
print(asp[0])
if ccalpha[3] == "S":
print(asp[1])
if ccalpha[3] == "E":
print(asp[2])
if ccalpha[3] == "G":
print(asp[3])
if ccalpha[3] == "P":
print(asp[4])
if ccalpha[1] == "E":
aep = [ccint*50, ccint*5 ,ccint , ccint/2, ccint/20]
if ccalpha[3] == "C":
print(aep[0])
if ccalpha[3] == "S":
print(aep[1])
if ccalpha[3] == "E":
print(aep[2])
if ccalpha[3] == "G":
print(aep[3])
if ccalpha[3] == "P":
print(aep[4])
if ccalpha[1] == "G":
agp = [ccint*100, ccint*10, ccint*2, ccint, ccint/10]
if ccalpha[3] == "C":
print(agp[0])
if ccalpha[3] == "S":
print(agp[1])
if ccalpha[3] == "E":
print(agp[2])
if ccalpha[3] == "G":
print(agp[3])
if ccalpha[3] == "P":
print(agp[4])
if ccalpha[1] == "P":
app = [ccint*1000, ccint*100, ccint*20, ccint*10, ccint]
if ccalpha[3] == "C":
print(app[0])
if ccalpha[3] == "S":
print(app[1])
if ccalpha[3] == "E":
print(app[2])
if ccalpha[3] == "G":
print(app[3])
if ccalpha[3] == "P":
print(app[4])
您始终可以使用字典进行查找:
lookup = {'C': {'C': ccint, 'S': ccint/10, 'E': ccint/50, 'G': ccint/100, 'P': ccint/1000},
'S': {'C': ccint*10, 'S': ccint, 'E': ccint/10, 'G': ccint/10, 'P': ccint/100},
'E': {'C': ccint*50, 'S': ccint*5, 'E': ccint, 'G': ccint/2, 'P': ccint/20},
'G': {'C': ccint*100, 'S': ccint*10, 'E': ccint*2, 'G': ccint, 'P': ccint/10},
'P': {'C': ccint*1000, 'S': ccint*100, 'E': ccint*20, 'G': ccint*10, 'P': ccint}
}
然后,您的所有if
主要包括:
print(lookup[ccalpha[1]][ccalpha[3]])
但是,是否可能包含其他字符?然后你需要引入一个后备方案:
try:
print(lookup[ccalpha[1]][ccalpha[3]])
except KeyError:
# Failed to find an entry for the characters:
print(ccalpha[1], ccalpha[3], "combination wasn't found")
如前所述,它不是最有效的方法,因为它每次都计算每个转换(即使是不必要的转换)。有一个基线(例如P
)并保存系数可能更有效:
lookup = {'C': 1000,
'S': 100,
'E': 50,
'G': 10,
'P': 1,
}
# I hope I have them the right way around... :-)
print(ccint * lookup[ccalpha[3]] / lookup[ccalpha[1]])
不应直接从源单元转换到目标单元,而应分两步进行:
factors = { 'CP': 1, 'SP': 10, and so on }
def convert_currency(amount, from_unit, to_unit):
copper = amount * factors[from_unit]
return copper / factors[to_unit]
这个代码就是你所需要的。你可以这样称呼它:
print(convert_currency(12345, 'SP', 'EP'))
另一种方法是使用矩阵(实际上只是列表列表):
首先创建货币转换矩阵。
然后将货币与一个数字进行匹配(就像C或Java等其他语言中的enum
)。为此,您使用了一个字典:它类似于一个列表,只是您定义了索引(它不是从0到长度-1)。
然后得到适当的转换率,将其与数字相乘,然后打印出来
这与MSeifert答案非常相似,只是您使用的词典较少,所以如果您不习惯使用这些词典,可能更容易理解 您熟悉字典吗?我很抱歉,您可以使用字典而不是if语句,但是对于您所使用的较小表达式,效率变得毫无意义,因为if语句对于较小表达式来说已经快得多了。但字典确实提供了更好的可读性。提供更好可读性的另一个方法是使用for循环或生成器,但字典提供了更好的可读性和效率,因此其更好的选项()(MSeifert提供了所需的字典)您也可以尝试模块中的正则表达式。我以前没有使用过字典,它们看起来像数组?对于打印(查找[ccalpha[1]][ccalpha[3]])
,它将转到相应的字母,然后进入{}集合以查找[3]的字母?我想确保我的理解是正确的。谢谢。字典由键值对组成,而不是通过索引(如数组)访问项目,而是通过键访问它们,例如,如果ccalpha[1]='S'
和ccalpha[3]='E'
这将首先获得'S'
的字典:{C':ccint*10,'S':ccint,'E':ccint/10,'G':ccint/10,'P':ccint/100}
然后选择'E'
的值:ccint/10
。此代码计算所有可能的转换,但只使用其中一个。因此,这是低效的。@RolandIllig指出,我已经包括了一个替代方案,它不会每次都计算它们。除了偏好之外,是否有任何具体的原因使用一个替代方案(矩阵和字典)?这取决于你在做什么,在这里我看不到任何原因。
conversion_rate = [[1, 1 / 10, 1 / 50, 1 / 100, 1 / 1000],
[1 * 10, 1, 1 / 10, 1 / 10, 1 / 100],
[1 * 50, 1 * 5, 1, 1 / 2, 1 / 20],
[1 * 100, 1 * 10, 1 * 2, 1, 1 / 10],
[1 * 1000, 1 * 100, 1 * 20, 1 * 10, 1]]
currency_value = {'C':0,'S': 1, 'E': 2, 'G': 3, 'P': 4}
from_ = currency_value[ccalpha[1]]
to = currency_value[ccalpha[3]]
print(ccint*conversion_rate[from_][to])