目前,我正在使用 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
元组(传入的“operator”函数的返回值),然后您将访问该列表的第一个和第二个值,其余部分非常不言自明。
但是,当我尝试运行此程序时,我会收到错误索引超出元组范围
(引用:Hastebin 上的第 95 行)。因此,我切换到了一种新的逻辑,我将在其中显式添加参数。函数,但是(显然),运行时,出现错误,没有参数传递到函数中(最里面的函数 --> Five()
in 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
。这是一个问题,特别是如果 n2
为 0
,除法 n1/n2
将失败并出现异常 ZeroDivisionError
。
一种解决方案是使用函数字典而不是数字字典:
def operator(op, n1, 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
(或 truediv
)。 Refer to the documentation on module operator
.例如,operator.add(x,y) 与 x+y 同义。但是你可以写一些有趣的东西,比如 return operator.add
,但你不能在 python 中写 return (+)
。
由于该模块已被称为 operator
,因此您可能应该为您的 operator
函数找到另一个名称。
import operator
def nine(arr=None):
if arr is None:
return 9
else:
return exec_op(arr[0], 9, arr[1])
def plus(num): # your code here
return ["+", num]
def exec_op(op, n1, 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
的默认参数来进一步简化:
identity = lambda x: x
def plus(y):
return lambda x: x+y
def nine(op=identity):
return op(9)
print(nine(plus(nine())))
# 18
关于python - 有没有办法将列表输入到Python 3.6中以*args作为参数的函数中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64785738/