2011-01-23 16 views
2

在試圖理解如何使用lambda時,我遇到了一個回覆,其中的招貼說你不能使用lambda來做任何事,你不能使用普通函數。在Python中將lambda翻譯爲普通函數

我一直在努力從Python本身內部調用一個函數,但不是專家,但我正在學習,並且遇到了一些問題,您需要使用遞歸函數,多次調用以獲取肯定的答案。

一個傢伙已經使用lambda函數來做到這一點,我試圖理解它,但我失敗了,所以我雖然如果函數可以使用普通函數來實現,那麼從這一點開始理解lambda會更容易。

讓我們這個句子例如:

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:]) 

這已經在Facebook的黑客杯被使用,正如我在圈失去了我解決不了這個問題。

這句話花費了幾句話,讓我們說「#1岩石,它是偉大的」

問題聲明Facebook是:

您已經截獲使用一個有趣的和愚蠢的加密系列變速器方法,你已經設法解密。這些消息只包含空格和小寫英文字符,並按如下加密:對於一個句子中的所有單詞,將第i個單詞(從1開始)的單詞替換爲應用以下遞歸操作f(word,i)生成的單詞, :

如果單詞的長度小於或等於i,則返回單詞 。 否則,返回f(詞的右半部分,i)+ f(詞的左半部分,i)。

如果單詞的長度是奇數,則將其分割爲右側較長。你已經決定與發送消息的人一起玩,並且以他們正在使用的相同風格廣播你自己的消息。

輸入 您的輸入將以整數N開始,然後是換行符,然後是N個測試用例。每個案例由一個只包含空格和小寫字母的未加密句子組成,案例以換行符分隔。句子中不會有前導空格或尾隨空格,並且任何相鄰字符之間最多隻有1個空格字符

輸出 對於每種情況以換行符分隔,輸出應用後的加密句子的內容編碼方法如上所述。您可能會忽略傳統的大寫字母規則並堅持使用全部小寫字母。

約束條件 5≤N≤25 句子將包含不超過100個字符。

+3

有趣的問題(來自facebook的一個)。問題(你已經理解這個解決方案的問題)是n次嵌套lambda表達式,過長的行,短名稱和許多其他事情使它變得難以理解。 – delnan 2011-01-23 23:29:55

+0

您引用的示例並非來自現實世界,而且您也不會提出問題...... – 2011-01-23 23:55:49

+4

這與lambda表達式有關很少,並且更多地與展開代碼混淆有關。 – Falmarri 2011-01-24 00:00:42

回答

2

Python lambda只是簡單的語法糖。 「常規」函數具有與閉包相同的功能,因爲請記住,您可以在另一個函數內定義它們,就像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的一個例子,它我只能理解,並且很難在不知道更多上下文的情況下給出更好的名字(我沒有試圖破譯實際的問題陳述)。它可以被解開爲直接調用它自己的遞歸函數。

3

哇,這是一個醜陋的線的Python :)

功能和lambda表達式之間的唯一區別:您可以將其定義在同一行使用lambda。沒有辦法定義一個普通的函數,並且在不使用exec的情況下在一行的中間調用它,或者不推薦使用類似的東西。

的功能VS lambda表達式

示例 - 下面的實現大多是等價的:

# 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') 

Lambda表達式允許你寫非常難讀的代碼。例如:

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(' '))) 

我通常建議不要使用lambdas。這是我使用列表理解和加入/分割的單行版本:

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