2012-03-24 28 views
6

今日、私はhaskellを学び始めています。私がそれを行う間に、私がPythonで学んだアイディアのいくつかを実装しようとしています。しかし、私はこれを挑戦していると感じました。あなたはHaskellに関数を書くことができます。関数は引数として別の関数をとり、引数の順序を反転して同じ関数を返します。 Pythonで似たようなことをすることはできますか?たとえば、Pythonの関数の引数の順番を反転する

これはPythonで行うことができますか?

+1

私はあなたが* argsを使用して、その引数リストをreverse()することができると思います。 –

答えて

11

ネストされた関数定義を使用してPythonでクロージャを作成できます。純粋な機能的なスタイルで

>>> from functools import wraps 
>>> def flip(func): 
     'Create a new function from the original with the arguments reversed' 
     @wraps(func) 
     def newfunc(*args): 
      return func(*args[::-1]) 
     return newfunc 

>>> def divide(a, b): 
     return a/b 

>>> new_divide = flip(divide) 
>>> new_divide(30.0, 10.0) 
0.3333333333333333 
+0

ええ、はい、これはうまくいくはずです。 – yasar

+0

良いですが、少し冗長ではありません。 – georg

+2

@ thg435 'flip'の定義の時点でのみです。そのような冗長さは、フリップフロップの内部で何が起こっているのかを明らかにするので、*良い*冗長なIMHOです。 – Ben

6

flip = lambda f: lambda *a: f(*reversed(a)) 

def divide(a, b): 
    return a/b 

print flip(divide)(3.0, 1.0) 

もう少し興味深い例:

unreplace = lambda s: flip(s.replace) 

replacements = ['abc', 'XYZ'] 
a = 'abc123' 
b = a.replace(*replacements) 
print b 
print unreplace(b)(*replacements) # or just flip(b.replace)(*replacements) 
これは、元の関数を引数の順序を逆にして、呼び出す新しい関数を作成することができます
+5

いいえ、それは公正ではありません! @ Raymondの答えは実際には実用的な観点からはるかに優れています。なぜなら、スタックトレースを読みやすくするからです。このスレッドを読んだ人は、まず彼の答えを読むべきです。再考してください。 – georg

関連する問題