2011-01-23 7 views
2

ラムダの使い方を理解しようとしている間に、ラムダを使って何もできないと言った返信が1つありました。Pythonのラムダを普通の関数に変換する

私は、Pythonでそれ自体の中から関数を呼び出すのは難しいですが、専門家ではありませんが、学習しています。再帰関数を使用する必要がある場合、特定の答え。

男はラムダ関数を使ってそれを行いましたが、私はそれを理解しようとしましたが、失敗しました。しかし、関数が通常の関数を使って実装できるなら、その点からラムダを理解するのが簡単です。 。

はのは、例えば、この文を見てみましょう:これはFacebookのハッカーカップで使用されてきた

print"\n".join(" ".join([(lambda f:(lambda x:f(lambda*r:x(x)(*r)))(lambda x:f(lambda*r:x(x)(*r))))(lambda f:lambda q,n:len(q)<=n and q or f(q[len(q)/2:],n)+f(q[:len(q)/2],n))(k,z+1)for z,k in enumerate(i[:-1].split())]) for i in list(s)[1:]) 

私はループに失われたように、私はこの問題を解決することができませんでした。

この文はいくつかの単語を取り、のは言わせて「StackOverflowの岩をし、それは素晴らしいです」

のFacebookでの問題文は次のとおりです。

あなたは面白いと愚かを使用して暗号化送信のシリーズを傍受しましたあなたはそれを解読することができました。文中のすべての単語について、i番目の単語(1ベース)は、次の再帰的操作f(word、i)を適用することによって生成された単語に置き換えられます。 :

単語の長さがi以下の場合は、戻り値は です。 それ以外の場合は、f(単語の右半分、i)+ f(単語の左半分、i)を返します。

単語の長さが奇数の場合は、右側が長くなるように分割されます。あなたはメッセージを送信している人と少しでも楽しい時間を過ごし、自分のメッセージを使用しているのと同じスタイルで暗号化してブロードキャストすることに決めました。

入力 入力は整数Nで始まり、その後に改行が続き、次にN個のテストケースが続きます。各ケースは、スペースと小文字のみを含む暗号化されていない文で構成され、改行は改行で区切られます。文中に先頭または末尾の空白がなく、それ以外の文字の間に最大1つの空白文字があります。

出力 出力後、改行で区切られた、適用後の暗号文の内容符号化方法は、上でそれを説明する。従来の大文字の規則を無視して、小文字に固執することができます。

制約 5≦N≦25 文は100文字以下です。

+3

面白い問題(面白い問題です)。問題(解決策を理解している問題)は、n倍のネストされたラムダ、長すぎる行、短い名前など多くのことが判読不能な混乱を招くことです。 – delnan

+0

あなたが引用している例は現実世界からのものではなく、あなたは質問をしません。 –

+4

これはラムダとはあまり関係がなく、アンロールコードの難読化と関連しています。 – Falmarri

答えて

2

Pythonラムダは単純に構文的な砂糖です。 "Regular"関数は、lambdaと同じように別の関数の中で定義することができるので、クロージャのような同じ機能を持っています。ラムダオブジェクトを検査するときを除き

def some_func(): 
    some_expr_using(lambda args: 42) 

# becomes: 

def some_func(): 
    def unique_name(args): 
    return 42 
    some_expr_using(unique_name) 

は、その名前が上記のようにUNIQUE_NAMEではなく、「<ラムダ>」に設定され、他の表面的な詳細は、実際のソースコードは、それが振る舞うようにではなく、スペルする方法に関する。

def y(f): 
    def a(x): 
    def b(*r): 
     return x(x)(*r) 
    return f(b) 
    return a(a) 

def fx(f): 
    def x(q, n): 
    # changed "a and b or c": different semantics if b can be falsy 
    if len(q) <= n: 
     return q 
    else: 
     return f(q[len(q)/2:], n) + f(q[:len(q)/2], n) 
    return x 

print "\n".join(
    " ".join(y(fx)(k, z + 1) for z, k in enumerate(i[:-1].split())) 
    for i in list(s)[1:]) 

(。しかし、私はそれを正しく翻訳されてきた場合にのみ、ダブルチェック::P)あなたのコードのように書くことができ

このコードは、fixed-point combinatorの一例である

、どの私はほとんど理解していないし、より多くの文脈を知らなくても、より良い名前を付けるのは難しい(私は実際の問題文を解読しようとはしなかった)。名前で直接呼び出す再帰関数に解くことができます。

+0

私を許してください、私は正しいコードの間違った問題をコピーしました。私は元の投稿を編集し、正しいfacebookの問題を含んでいます。申し訳ありませんが、正直なところ – ma2moun

+0

@ ma2moun:私の答えは問題文ではなくコード行に基づいており、コード行を変更していないように見えるので、これはまだ適用されます。 –

+0

私はそれに気がついて答えとしてあなたの答えをマークしましたが、私は謝罪してすべての答えにコメントしました。 素晴らしい、ありがとう:) – ma2moun

3

うわーそれは、Pythonの醜いラインだ:)

機能とラムダの唯一の違い:あなたはそれを定義する同じ行のラムダを使用することができます。通常の関数を定義し、execのようなものを使わずに行の途中で呼び出す方法はありません。同様に推奨されていません。ラムダVS機能の

例 - 次の実装はほとんど同じです:

# the shortest numbers of lines required to define and call a normal function: 2 
def foo(bar): return bar 
print foo('baz') 

# this lambda has the exact same effect as the function "foo" above 
foo = lambda bar: bar 

# the shortest number of lines required to define and call a lambda: 1 
# note you can also call the lambda on the same line you define it 
# and you aren't required to even name a lambda 
print (lambda bar: bar)('baz') 

ラムダを使用すると、コードを読むことは非常に難しい書くことができます。例:

a = (lambda x: x+x)(1) # very long-winded way of saying "a = 1+1" 

Facebookの問題は、それを分解しましょう。

# for simplicity, let's say we're getting a single string 
# with a sentence on each line. 
text = ''' 
stackoverflow rocks and is great 
redundancy is the redundant king of the land 
without a foo, you cannot bar the baz 
''' 

# first, we'll strip() the text to remove the spaces at the edges 
# as these would create blank lines when splitting the text 
text = text.strip() 

# next, we'll split the text on the newline character, '\n' 
lines = text.split('\n') 

# now we have a list of lines, which we can easily walk through with a for loop 
for line in lines: 
    # now we're going to split all of the words from each line 
    # this is easy, just split with a space as the delimiter 
    words = line.split(' ') 

    # then we want to sort the words alphabetically 
    # list.sort() will easily sort a list in place 
    words.sort() 

    # now we want to recombine the line 
    # we're going to use join() for this 
    # we call join on a string, with a list: like 'foo'.join(list) 
    # join combines the list into a string 
    # placing the string between each item 

    # we're going to join with a blank string 
    # so our words will be all in a row with no spaces 
    sentence = ''.join(words) 

    # that's it! now we can just print the sorted result 
    print sentence 

これが結果です:これらは、ソートされた言葉だった

andgreatisrocksstackoverflow 
iskinglandofredundancyredundantthethe 
abarbazcannotfoo,thewithoutyou 

and great is rocks stackoverflow 
is king land of redundancy redundant the the 
a bar baz cannot foo, the without you 

ほとんど詩的:)

参照として、これは私の元に解決しましたFacebookの質問:

import sys 
q = open(sys.argv[1]).read().strip() 
for line in q.split('\n')[1:]: 
    print ''.join(sorted(line.split(' ',1)[1].split(' '))) 

ラムダを使用しないことをお勧めします。これは単なるリストの理解と結合/分割を使用した私の1行バージョンでした:

print '\n'.join([''.join(sorted(line.split(' '))) for line in text.split('\n') if line]) 
+0

私を許してください、私は正しいコードの間違った問題をコピーしました。 オリジナルの投稿を編集し、正しいfacebookの問題が含まれています。すみません、申し訳ありません。 – ma2moun

関連する問題