在 Python 3.6 中,有没有一种方法可以将列表输入到以 *args 作为参数的函数中?

Is there a way to input a list into a function which has *args as its argument in Python 3.6?

目前,我正在使用 Python 3.6 解决 CodeWars 上名为“函数计算训练”的问题。这个问题的工作方式是,例如,如果调用 seven(times(five())),那么函数应该 return 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")

完整代码在这个 link 上(有 -> 顶部和没有 -> 底部参数):Hastebin

我的逻辑(最初)是使用 *args 作为参数,如果 argsNone 那么函数将 return 它自己的值(five() => 5),然后这个值将被传递到 'operator' 函数之一,该函数将 return 它自己的运算符(即 +、-、/、*)和传递的数字的列表进去。然后,在最外层的函数中,您将从 'operator' 函数传入数组,因为 args 不是 None,您将获取 args 元组中的第一项(传入 'operator' 函数的 returned 值),然后您将访问该列表的第一个和第二个值,其余的不言自明。

但是,当我尝试 运行 时,我会得到错误 index beyond tuple range(参考:Hastebin 上的第 95 行)。因此,我切换到一个新的逻辑,我会在其中显式添加参数。函数,但是(很明显),当 运行 时,出现了一个错误,即没有参数被传递到函数中(最内层的函数 --> five() in seven(times(five())))。

我想知道是否有任何方法可以修复我现有的代码,但我们非常欢迎任何替代解决方案。

此外,这里有一个 link 套路: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。这是一个问题,特别是因为如果 n20.

,除法 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 中定义,并称为 addsubmulfloordiv(或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

另一种方式:使plusreturn成为函数

这是另一种方式,它不将操作存储为字符串和数字的列表,并且不需要额外的函数operator/exec_op来评估操作。

我们将 plus(y) 按字面意思 return 函数 ? + 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