python用法 - python plot title中文




Python中沒有多行Lambda:為什麼不呢? (6)

我聽說它說多線lambda不能在Python中添加,因為它們會與Python中的其他語法結構在語法上發生衝突。 我今天在公共汽車上想到了這一點,並意識到我無法想像多線lambdas碰撞的單個Python構造。 鑑於我非常了解這門語言,這讓我感到驚訝。

現在,我確定Guido有理由不在語言中包含多行lambda表達式,但是出於好奇:包括多行lambda表達式的情況會是什麼含糊不清的? 我聽說過的是真的,還是有其他原因,Python不允許多行lambda表達式?


Guido van Rossum(Python的發明者)在一篇舊的博客文章中自己回答了這個確切的問題。
基本上,他承認這在理論上是可行的,但是任何提議的解決方案都將是非Pythonic:

“但是對於這個難題,任何提議的解決方案的複雜性都是巨大的,對我而言:它需要解析器(或者更確切地說是詞法分析器)能夠在縮進敏感模式和縮進不敏感模式之間來回切換,保持堆棧以前的模式和縮進級別在技術上都可以解決(已經有一堆壓縮級別可以被推廣)但是沒有一個能夠帶走我的直覺,認為它都是精巧的Rube Goldberg裝置


[編輯]閱讀此答案。 它解釋了為什麼多行lambda不是一件事情。

簡而言之,它是和諧的。 來自Guido van Rossum的博客文章:

我發現任何解決方案都無法接受,在表達式的中間嵌入一個基於縮進的塊。 由於我發現語句分組的另一種語法(例如花括號或開始/結束關鍵字)同樣不可接受,這使得多行lambda成為難以解決的難題。

至於這個答案的其餘部分。 使用單行1 lambda或命名函數。 請不要使用exec - 我後悔曾經暗示過。

1你會驚訝你可以用一行python做什麼。

一種解決方法來獲取多行lambda函數(對skriticos的答案的擴展):

(lambda n: (exec('global x; x=4; x=x+n'), x-2)[-1])(0)

它能做什麼:

  • Python在讀取分隔符之前簡化(執行)元組的每個組件。

  • 例如, lambda x: (functionA(), functionB(), functionC(), 0)[-1]將執行所有三個函數,即使唯一使用的信息是列表中的最後一項(0)。

  • 通常你不能指定或聲明python中的列表或元組中的變量,但是使用你可以exec函數(注意它總是返回: None )。

  • 請注意,除非你聲明一個變量為global變量,否則它不會存在於該exec函數調用之外(這僅適用於lambda語句中的exec函數)。

  • 例如(lambda: exec('x=5;print(x)'))()沒有global聲明就可以正常工作。 然而, (lambda: (exec('x=5'), exec('print(x)')))()或者(lambda: (exec('x=5'), x)()不會。

  • 請注意,所有global變量都存儲在全局名稱空間中,並且在函數調用完成後將繼續存在。 出於這個原因,這不是一個好的解決方案,應盡可能地避免。 從lambda函數中的exec函數聲明的global變量與global名稱空間保持分離。 (在Python 3.3.3中測試)

  • 元組末尾的[-1]獲取最後一個索引。 例如[1,2,3,4][-1]4 。 這樣做只會返回所需的輸出值,而不是包含exec函數和其他無關值的整個元組。

等效多線功能:

def function(n):
    x = 4
    x = x+n
    return x-2

function(0)

避免需要多線lambda的方法:

遞歸:

f = lambda i: 1 if i==0 or i==1 else f(i-1)+f(i-2)

布爾是整數:

lambda a, b: [(0, 9), (2, 3)][a<4][b>3]

迭代器:

lambda x: [n**2 for n in x] #Assuming x is a list or tuple in this case

一些相關的鏈接:

一段時間以來,我一直在關注Reia的開發,最初將基於Python的基於縮進的語法與Ruby塊一起,都在Erlang之上。 但是,設計師最終放棄了縮進靈敏度,他在這篇文章中寫到的這個決定包括討論他遇到的縮進+多行塊問題,以及他為Guido的設計問題/決定獲得的增加的讚賞:

http://www.unlimitednovelty.com/2009/03/indentation-sensitivity-post-mortem.html

另外,這裡有一個關於Python中Ruby風格塊的有趣建議,我跑過Guido發布了一個沒有實際拍攝的回應(不確定是否有任何後續的拍攝):

http://tav.espians.com/ruby-style-blocks-in-python.html


看看以下內容:

map(multilambda x:
      y=x+1
      return y
   , [1,2,3])

這是一個lambda返回(y, [1,2,3]) (因此map只有一個參數,導致錯誤)? 或者它返回y ? 或者它是語法錯誤,因為新行上的逗號放錯了位置? Python如何知道你想要什麼?

在parens中,縮進與python無關,所以你不能毫不含糊地使用多行。

這只是一個簡單的例子,可能有更多的例子。


讓我試著解決@balpha解析問題。 我會在多行lamda中使用括號。 如果沒有括號,則lambda定義是貪婪的。 所以lambda在

map(lambda x:
      y = x+1
      z = x-1
      y*z,
    [1,2,3]))

返回一個函數返回(y*z, [1,2,3])

map((lambda x:
      y = x+1
      z = x-1
      y*z)
    ,[1,2,3]))

手段

map(func, [1,2,3])

func是返回y * z的多行lambda。 那樣有用嗎?


這通常是非常醜陋的(但有時替代品更難看),所以一種解決方法是製作大括號表達式:

lambda: (
    doFoo('abc'),
    doBar(123),
    doBaz())

它不會接受任何任務,所以你必須事先準備好數據。 我發現這個地方有用的地方是PySide包裝器,你有時候會有短的回調。 編寫額外的成員函數會更加難看。 通常你不會需要這個。

例:

pushButtonShowDialog.clicked.connect(
    lambda: (
    field1.clear(),
    spinBox1.setValue(0),
    diag.show())






lambda