假设你有这样的价值:
n = 5
和一个返回它的阶乘的方法,如下所示:
因子(5)
如何处理多个值:
nums = [1,2,3,4,5]
因子(nums)
所以它将所有这些值的阶乘返回为列表。
如果不编写2种方法,最简单的方法是什么? python是否有很好的方法来处理这种情况?
答案 0 :(得分:13)
def Factorial(arg):
try:
it = iter(arg)
except TypeError:
pass
else:
return [Factorial(x) for x in it]
return math.factorial(arg)
如果它是可迭代的,则应用recursivly。否则,正常进行。
或者,您可以将最后一个return
移到except
块中。
如果您确定Factorial
的正文永远不会TypeError
,则可以将其简化为:
def Factorial(arg):
try:
return [Factorial(x) for x in arg]
except TypeError:
return math.factorial(arg)
答案 1 :(得分:9)
[fac(n) for n in nums]
修改强>
抱歉,我误解了,你想要一个处理序列和单值的方法吗?我无法想象为什么你不会用两种方法做到这一点。
def factorial(n):
# implement factorial here
return answer
def factorial_list(nums):
return [factorial(n) for n in nums]
另一种方法是进行某种类型检查,除非你有一些非常令人信服的理由,否则最好避免这样做。
编辑2:
MizardX的答案更好,投票给那个。欢呼声。
答案 2 :(得分:7)
有时会这样做。
def factorial( *args ):
def fact( n ):
if n == 0: return 1
return n*fact(n-1)
return [ fact(a) for a in args ]
它提供了一个几乎神奇的功能,可以使用简单的值和序列。
>>> factorial(5)
[120]
>>> factorial( 5, 6, 7 )
[120, 720, 5040]
>>> factorial( *[5, 6, 7] )
[120, 720, 5040]
答案 3 :(得分:6)
如果你问Python是否可以进行方法重载:没有。因此,像这样的多方法是一种非Pythonic定义方法的方法。另外,命名约定通常是大写的类名和小写的函数/方法。
如果你想继续前进,最简单的方法就是成为一个分支:
def Factorial(arg):
if getattr(arg, '__iter__', False): # checks if arg is iterable
return [Factorial(x) for x in arg]
else:
# ...
或者,如果你感觉很花哨,你可以让装饰师为任何功能做这个:
def autoMap(f):
def mapped(arg):
if getattr(arg, '__iter__', False):
return [mapped(x) for x in arg]
else:
return f(arg)
return mapped
@autoMap
def fact(x):
if x == 1 or x == 0:
return 1
else:
return fact(x-1) + fact(x-2)
>>> fact(3)
3
>>> fact(4)
5
>>> fact(5)
8
>>> fact(6)
13
>>> fact([3,4,5,6])
[3, 5, 8, 13]
虽然更多的Pythonic方法是使用变量参数长度:
def autoMap2(f):
def mapped(*arg):
if len(arg) != 1:
return [f(x) for x in arg]
else:
return f(arg[0])
return mapped
@autoMap2
def fact(n):
# ...
>>> fact(3,4,5,6)
[3, 5, 8, 13]
将两者组合成一个深度的映射装饰器:
def autoDeepMap(f):
def mapped(*args):
if len(args) != 1:
return [mapped(x) for x in args]
elif getattr(args[0], '__iter__', False):
return [mapped(x) for x in args[0]]
else:
return f(args[0])
return mapped
@autoDeepMap
def fact(n):
# ...
>>> fact(0)
1
>>> fact(0,1,2,3,4,5,6)
[1, 1, 2, 3, 5, 8, 13]
>>> fact([0,1,2,3,4,5,6])
[1, 1, 2, 3, 5, 8, 13]
>>> fact([0,1,2],[3,4,5,6])
[[1, 1, 2], [3, 5, 8, 13]]
>>> fact([0,1,2],[3,(4,5),6])
[[1, 1, 2], [3, [5, 8], 13]]
答案 4 :(得分:3)
或者,如果您不喜欢列表推导语法,并希望跳过新方法:
def factorial(num):
if num == 0:
return 1
elif num > 0:
return num * factorial(num - 1)
else:
raise Exception("Negative num has no factorial.")
nums = [1, 2, 3, 4, 5]
# [1, 2, 3, 4, 5]
map(factorial, nums)
# [1, 2, 6, 24, 120, 720]
答案 5 :(得分:3)
你可能想看看NumPy / SciPy的vectorize。
在numpy世界中,鉴于你的单一因子阶乘函数, 你会做像
这样的事情 vFactorial=np.vectorize(Factorial)
vFactorial([1,2,3,4,5])
vFactorial(6)
虽然注意到最后一种情况返回单元素numpy数组而不是raw int。