2009-12-15 48 views
6

考慮下面的代碼:Lisp風格風格`let`在Python列表內涵語法

>>> colprint([ 
     (name, versions[name][0].summary or '') 
     for name in sorted(versions.keys()) 
    ]) 

這段代碼的含義是打印字典versions的元素在其keys依次遞增,但由於value是另一個排序列表,僅打印其的第一個元素(「最大」)的摘要。

因爲我熟悉let從口齒不清,我重寫了上面:

>>> colprint([ 
     (name, package.summary or '') 
     for name in sorted(versions.keys()) 
     for package in [versions[name][0]] 
    )] 

你認爲這違反了being Pythonic?可以改進嗎?

注意:爲了好奇,colprint定義爲here

+3

heh。嘗試成爲lispy是不可寬恕的。 Python儘可能地努力不做任何事情。 – Svante

+2

很難用口齒說話給Parsel; [。 – Tordek

+0

python不會嘗試不像lisp。 GvR自己曾經說過,PYthon和Lisp非常相似,而且差異更爲膚淺。我自己是從一個計劃中退出來的,但是我現在幾乎完全使用python了三年,而且我喜歡第一種方式比第一種方式多。 – Broseph

回答

7

爲什麼不利用元組?

colprint([(name, version[0].summary or '') 
     for (name, version) in sorted(versions.iteritems())]) 

,或者甚至

colprint(sorted([(name, version[0].summary or '') 
      for (name, version) in versions.iteritems()])) 

此外,您可以考慮(在我的第一個例子)去除[] S,因爲這樣你會得到一臺發電機,而不是一個列表(可能會或可能不會是有用的,因爲我猜這會打印整個數組,所以你不會保存任何評估)。

+0

我即將建議相同 –

+0

看起來更好;除了我會使用'items()'而不是'iteritems()',因爲在Py3k中已經廢棄了(而且'colprint'總是接受一個扁平列表) –

4

因此,您使用「for x in [y]」作爲「let x y」的替代品。

試圖在另一種語言中模擬語言的語法從來就不是一個好主意。我認爲原始版本更清晰。

0

您可以將排序移動到最後以避免一些中間列表。

這看起來更好一點我猜:

colprint(sorted(
     (name, version[0].summary or '') 
     for (name,version) in versions.iteritems()) 
    )) 

Python3可以做得更好:

colprint(sorted(
     (name, first_version.summary or '') 
     for (name,(first_version,*_)) in versions.items()) 
    )) 
+1

?這是什麼語言?我在Python中出現語法錯誤。 –

+2

第二個是Python ** 3 ** –

5

我不會用「刁鑽的條款」(或「讓當量」 )在大多數情況下,但如果這是避免重複的自然方法,尤其是昂貴的重複。例如。

xs = [(y, y*1.2, y-3.4) for z in zs for y in [somefun(z)] ] 

看起來比調用somefun三次好得多我 - !)所以,這是值得銘記,即使可能不值得使用它不會刪除重複。

1

由於Tordek說,你可以使用items()iteritems()在這種情況下,爲了避免這個問題:

colprint(sorted((name, packages[0].summary or '') 
       for (name, packages) in versions.items())) 

移動外的排序是一個很好的接觸。

[請注意,items()的使用稍微改變了排序順序 - 它以前是通過名字來確定按照原始順序解析的關係(Python排序是穩定的),現在它的名稱以關係通過摘要解決。由於字典的原始順序是隨機的,因此新行爲可能會更好。]

但對於其他用途(例如Alex Martelli的示例),「let」類似仍可能有用。 我也曾經發現過for var in [value]的詭計,但我現在覺得它很難看。 甲清潔的替代可能是一個推導/發電機中的「管道」,使用「裝飾/去除裝飾」誘騙在元組傳遞的附加值:

# You could write this with keys() or items() - 
# I'm just trying to examplify the pipeline technique. 
names_packages = ((name, versions[name][0]) 
        for name in versions.keys()) 

names_summaries = ((name, package.summary or '') 
        for (name, package) in names_packages) 

colprint(sorted(names_summaries)) 

或施加至Alex的例子:

ys = (somefun(z) for z in zs) 
xs = [(y, y*1.2, y-3.4) for y in ys] 

(其中你甚至不需要原來的z值,因此中間值不必是元組。)

http://www.dabeaz.com/generators/的「管道」技術的更強大的例子...