问题描述
当前,我正在使用Python 3.6处理CodeWars上的一个名为“函数计算培训”的问题。例如,如果调用了seven(times(five()))
,则此问题的工作方式将返回35。这是我的代码段:
def nine(arr): # your code here
if arr is None:
return 9
return operator(arr[0],9,arr[1])
def plus(num): # your code here
return ["+",num]
def operator(op,n1,n2):
switcher = {
"+": n1 + n2,"-": n1 - n2,"*": n1 * n2,"/": n1 / n2
}
return switcher.get(op,"Invalid")
完整的代码在此链接上(带有->顶部和没有->底部参数):Hastebin
这里的逻辑(最初)是使用*args
作为参数,如果args
是None
,则该函数将返回其自己的值(five() => 5
),然后,该值将被传递到“运算符”函数之一,该函数将返回其自身运算符的列表(即+,-,/,*)以及传递给它的数字。然后,在最外面的函数中,您将从'operator'函数中传入数组,因为args
不是None
,因此您将在args
元组中使用第一项(从传入的“运算符”函数返回的值),然后您将访问该列表的第一个和第二个值,其余的很不言自明。
但是,当我尝试运行此命令时,会出现错误index beyond tuple range
(参考:Hastebin的第95行)。结果,我切换到新的逻辑,在该逻辑中我将显式添加参数。该函数,但是(显然)在运行时,出现错误,没有向函数传递任何参数(five()
中最里面的函数-> seven(times(five()))
)。
我想知道是否有什么办法可以修复现有代码,但是任何替代解决方案都值得欢迎。
此外,这是指向kata的链接:Codewars Kata
解决方法
您可以为参数提供默认值。如果未传递任何参数,则将使用默认值。由于您检查了None
,因此可以使用None
作为默认值。
def nine(arr=None):
if arr is None:
return 9
else:
return operator(arr[0],9,arr[1])
def five(arr=None):
if arr is None:
return 5
else:
return operator(arr[0],5,arr[1])
def plus(num): # your code here
return ["+",num]
def operator(op,n1,n2):
switcher = {
"+": n1 + n2,"-": n1 - n2,"*": n1 * n2,"/": n1 / n2
}
return switcher.get(op,"Invalid")
print(nine(plus(five()))
# 14
问题与您的operator
函数有关:python dict
是不懒惰的
请注意,python dict
不是惰性的。这意味着,当您以自己的方式定义switcher
时,它将立即执行四个计算n1 + n2,n1 - n2,n1 * n2,n1 / n2
。这是一个问题,尤其是因为如果n1 / n2
为ZeroDivisionError
,则除n2
的除法会失败,并抛出异常0
。
一种解决方案是使用函数字典而不是数字字典:
def operator(op,n2):
switcher = {
"+": lambda x,y: x+y,"-": lambda x,y: x-y,"*": lambda x,y: x*y,"/": lambda x,y: x/y,}
return switcher[op](n1,n2)
请注意,这四个函数已在python模块operator
中定义,分别称为add
,sub
,mul
,floordiv
(或{{ 1}})。 Refer to the documentation on module operator
.例如,truediv
是operator.add(x,y)
的同义词。但是您可以编写有趣的内容,例如x+y
,而不能在python中编写return operator.add
。
由于此模块已被称为return (+)
,因此您可能应该为operator
函数找到另一个名称。
operator
另一种方式:使import operator
def nine(arr=None):
if arr is None:
return 9
else:
return exec_op(arr[0],num]
def exec_op(op,n2):
switcher = {
"+": operator.add,"-": operator.sub,"*": operator.mul,"/": operator.floordiv
}
return switcher[op](n1,n2)
print(nine(plus(nine())))
# 18
返回一个函数
这是另一种方法,它不将操作存储为字符串和数字列表,并且不需要额外的函数plus
/ operator
来评估操作。
我们将使exec_op
从字面上返回函数plus(y)
。
? + y
我们可以通过使用函数代替def plus(y):
return lambda x: x+y
def nine(op=None):
if op is None:
return 9
else:
return op(9)
print(nine(plus(nine())))
# 18
作为None
的默认参数来进一步简化此操作:
nine