は、あなたがこのように価値があるとしましょう:Pythonで単一値と複数値の両方をカバーする単一の実装ですか?
のn = 5
などのように、それの階乗を返すメソッド:
階乗(5)
あなたはどのように扱いますか複数の値:
NUMSの= [1,2,3,4,5]
階乗(NUMS)
だから、これらすべての値の階乗をリストとして返します。
これを処理する最もクリーンな方法は2つの方法を記述することなくですか?これらの状況を処理するには、Pythonには良い方法がありますか?
は、あなたがこのように価値があるとしましょう:Pythonで単一値と複数値の両方をカバーする単一の実装ですか?
のn = 5
などのように、それの階乗を返すメソッド:
階乗(5)
あなたはどのように扱いますか複数の値:
NUMSの= [1,2,3,4,5]
階乗(NUMS)
だから、これらすべての値の階乗をリストとして返します。
これを処理する最もクリーンな方法は2つの方法を記述することなくですか?これらの状況を処理するには、Pythonには良い方法がありますか?
これが時々行われている:あなたはFactorial
の体はTypeError
を上げることは決してありません確信している場合に
、それを簡略化することができました。
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]
最もクリーンな答えはこれまでのところ... –
入力が単純な数値であってもリストを返すので、良くありません。 –
私は要件が何であるかについて完全には不明です。リストと個々の値を魔法のように「均一な」方法で扱う関数の考え方は混乱します。またはそれはAPL(またはJまたはK)です。 –
[fac(n) for n in nums]
EDIT:
申し訳ありませんが、私は、あなたが両方の配列や単一の値を処理するメソッドをしたい誤解?なぜあなたが2つの方法でこれをしないのか想像できません。
def factorial(n):
# implement factorial here
return answer
def factorial_list(nums):
return [factorial(n) for n in nums]
これに代わる方法は、何らかの型チェックを行うことです。これは、非常に魅力的な理由がある場合を除いて避けてください。
EDIT 2:
MizardXの答えは優れている、1つに投票します。乾杯。
Pythonがメソッドのオーバーロードを実行できるかどうかを確認する場合は、次のようにします。したがって、そのような複数のメソッドを実行することは、メソッドを定義するむしろPython以外の方法です。また、大文字小文字を区別するための大文字小文字のクラス名、小文字の関数/メソッドの命名規則。
あなたはとにかく先に行きたい場合は、最も簡単な方法は、単にブランチを作るために次のようになります。
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]
よりPython的な方法は、可変引数の長さを使用することであるが:
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]
Pディープマッピングデコレータに2つのウッティング・アム・アンマーゼー:それは反復可能なら
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]]
デコレータを再帰的にするには、argのxの[f(x)]を[argのxのmapped(x)]に変更します。 –
MizardX:あなたは私の心を吹き飛ばした。いいアイデア:) –
しかし、これはフィボナッチです... :) –
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
ブロックに移動することもできます。
def Factorial(arg):
try:
return [Factorial(x) for x in arg]
except TypeError:
return math.factorial(arg)
getattr(obj、 '__iter__'、False)は、 'obj'がtry/except(遅いかもしれない)なしでiterableであるかどうかをチェックする方法です。 –
@Andrey Fedorov:ほとんどの場合、try/exceptは実際にはより高速です。 –
@MizardX: 'Factorial'のボディがあなたの前にあります。したがって、 'arg'が反復可能でないときに、' TypeError' *が生成されることを確実にすることができます。上記の2つのバージョンのFactorialは同じことをしますが、より単純です。 – jfs
それとも、リスト内包構文を好きで、新しいメソッドを持つスキップしたくない場合:
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]
あなたがnumpyの/ scipyのダウンロードのvectorizeを見てみたいことがあります。 numpyの世界では
は、あなたが最後のケースは、生ではなく、単一要素のnumpyの配列を返すことに注意してくださいもののvFactorial=np.vectorize(Factorial)
vFactorial([1,2,3,4,5])
vFactorial(6)
のようなものにしてくださいあなたの単一のint-argの階乗機能、 を与えられましたint。
スカラーを使ったこととベクトルを使ったことのうちの1つを行ったような魔法の関数のユースケースについて、いくつかの背景を教えてください。 –
単一の値がそれほど有用ではないように見えますが、SumやAverageなどの関数には適しています。このように使用できる多くの機能があります。 –
いいえ、値が1つだけの場合は、この単一の値を含むリストを使用してください。オブジェクトが似たように振る舞う場合、異なる型を返すことは大丈夫です。しかし、これは限界をはるかに超えています。 –