2017-07-25 45 views
1

當進行數據處理任務時,我經常發現自己將一系列合成,矢量化函數等應用於某些輸入可迭代數據以生成最終結果。理想情況下,我希望能夠爲列表和生成器(除了任何其他迭代器)提供支持的東西。我可以想出許多方法來構建代碼來實現這一目標,但我所能想到的每種方法都有一種或多種方法讓我感到不潔/單一。我在下面概述了我可以想到的不同方法來做到這一點,但我的問題是 - 有沒有一種推薦的,慣用的方法來做到這一點?用於將循序步驟應用於迭代的Python成語

方法我能想到的,一個簡單的例子示出的,其通常是代表:

寫入它作爲一個大的表達

result = [sum(group) 
      for key, group in itertools.groupby(
       filter(lambda x: x <= 2, [x **2 for x in input]), 
       keyfunc=lambda x: x % 3)] 

這通常是相當困難的閱讀任何非平凡的一系列步驟。閱讀代碼時,還會遇到相反的每一步。

保存每個步驟變成不同的變量名稱

squared = [x**2 for x in input] 
filtered = filter(lambda x: x < 2, squared) 
grouped = itertools.groupby(filtered, keyfunc=lambda x: x % 3) 
result = [sum(group) for key, group in grouped] 

這引入了許多局部變量,往往可能很難名稱描述性的;此外,如果某些或所有中間步驟的結果特別大,請將其留在內存中可能會造成很大的內存浪費。如果有人想爲這個過程添加一個步驟,必須注意所有變量名稱都要正確更新 - 例如,如果我們希望將每個數字除以2,我們將添加行halved = [x/2.0 for x in filtered],但也必須記住更改filteredhalved在下面的行。

商店每個步驟變成相同的變量名

tmp = [x**2 for x in input] 
tmp = filter(lambda x: x < 2, tmp) 
tmp = itertools.groupby(tmp, keyfunc=lambda x: x % 3) 
result = [sum(group) for key, group in tmp] 

我想這對我來說是最不壞的這些選項,但在一般命名佔位符變量存放東西的感覺未Python的我,讓我懷疑在那裏有更好的方法。

+0

這在很大程度上是一個意見和首選風格的問題。還有其他的樣式,例如['流暢的界面'](https://en.wikipedia.org/wiki/Fluent_interface)或['方法鏈接'](https://en.wikipedia.org/wiki/Method_chaining),這將允許更自然的級聯的電話。 – AChampion

回答

1

代碼審查往往是一個更好的風格問題的地方。 SO更多的是解決問題。但CR可能會對示例的完整性產生挑剔。

但我不能幾點意見:

  • ,如果你換這個計算的功能,命名是沒有什麼大不了的。這些名稱不必具有全球意義。

  • 您的許多表達式都是生成器。 Itertools傾向於產生髮電機或發電機。表達式。所以內存使用不應該是一個問題。


def better_name(input): 
    squared = (x**2 for x in input) # gen expression 
    filtered = filter(lambda x: x < 2, squared) 
    grouped = itertools.groupby(filtered, lambda x: x % 3) 
    result = (sum(group) for key, group in grouped) 
    return result 

list(better_name(input)) 

使用def功能,而不是lambda表達式也可以使代碼更清晰。有一個折衷。你的lambda很簡單,我可能會保留它們。

你的第二個選項比第一個選項更可讀。表達式的順序指導我的閱讀和心理評估。在第一次,很難確定最內部或第一次評估。 groupby是一個複雜的操作,所以任何幫助分區的行動是受歡迎的。


filter文檔,這些都是等價的:

filtered = filter(lambda x: x < 2, squared) 
filtered = (x for x in squared if x<2) 

我錯過了return。該函數可以返回一個生成器,或者是一個評估列表。

groupbykeyfunc不是一個關鍵字參數,而是一個關鍵字參數。

groupby是複雜的功能。它返回一個生成元組的生成器,其元素是一個生成器本身。回過頭來讓它更加明顯。

((key, list(group)) for key, group in grouped) 

因此,一個明確其使用的代碼風格是可取的。