2012-11-14 64 views
0

我找到了一個函數,它接收一個列表並返回一個字符串。 但是,我很難理解它在做什麼?請評論下面的代碼:需要了解一個函數,其中包括lambdas

def getAsTable(self, arrays): 
    """ This method takes an array of arrays and returns string (which is really a table) 
    :param arrays: An array of arrays 
    :returns: string (this is really a table of the input) 

    >>> [[a, b, b], [1, 2, 3], [4, 5, 6]] 
    >>> a b c 
    >>> 1 2 3 
    >>> 4 5 6 

    """ 
    def areAllEqual(lst): 
     return not lst or [lst[0]] * len(lst) == lst 

    if not areAllEqual(map(len, arrays)): 
     return "Cannot print a table with unequal array lengths" 

    verticalMaxLengths = [max(value) for value in map(lambda * x:x, *[map(len, a) for a in arrays])] 
    spacedLines = [] 

    for array in arrays: 
     spacedLine = '' 
     for i, field in enumerate(array): 
      diff = verticalMaxLengths[i] - len(field) 
      spacedLine += field + ' ' * diff + '\t' 
     spacedLines.append(spacedLine) 

    return '\n '.join(spacedLines) 

回答

2

map一個簡短的說明從而節省了我不必垃圾下面的代碼註釋:

map功能應用的第一個參數(通常是功能,但能成爲一個類或任何其他可調用的東西)到第二個參數中的每個值並返回結果列表。把它看作是用給定函數轉換每個元素。使用兩個參數,它的工作原理是這樣的:

def map(fct, iterable): return [fct(x) for x in iterable] 

使用三個或更多的參數,map假設後的第一個所有參數均爲iterables和遍歷它們並聯,通過每個迭代的第n個元素上第n通功能:

def p(a,b,c): print "a: %s, b:%s, c:%s" 
map(p, "abc", "123", "456") #-> prints "a 1 4", then "b 2 5", then "c 3 6" 

用註釋代碼的版本:

def getAsTable(self, arrays): 

    #helper function checking that all values contained in lst are equal 
    def areAllEqual(lst): 
     #return true for the empty list, or if a list of len times the first 
     #element equals the original list 
     return not lst or [lst[0]] * len(lst) == lst 

    #check that the length of all lists contained in arrays is equal 
    if not areAllEqual(map(len, arrays)): 
     #return an error message if this is not the case 
     #this should probably throw an exception instead... 
     return "Cannot print a table with unequal array lengths" 

    verticalMaxLengths = [max(value) for value in map(lambda * x:x, *[map(len, a) for a in arrays])] 

我們分這條線到它的部分:

(1) [map(len, a) for a in arrays] 

這len個映射到陣列的每個表 - 這意味着你得到的元素的長度 名單列表。例如,對於輸入[["a","b","c"], ["1","11","111"], ["n", "n^2", "n^10"]],結果將是[[1, 1, 1], [1, 2, 3], [1, 2, 4]]

(2) map(lambda *x:x, *(1)) 

*解開傳遞給映射作爲單獨的參數中獲得的列表(1),這意味着每個元素是 。如上所述,使用 多個參數,map將a傳遞給該函數。此處定義的lambda 只是將其所有參數作爲元組返回。 繼續上面的例子,對於輸入[[1, 1, 1], [1, 2, 3], [1, 2, 4]] 結果將是[(1, 1, 1), (1, 2, 2), (1, 3, 4)] 這基本上會導致輸入

(3) [max(value) for value in (2)] 

這在列表的所有元素中返回(2)(保持在調用最大的矩陣轉置介意元素是元組)。對於輸入[(1, 1, 1), (1, 2, 2), (1, 3, 4)],結果將是[1, 2, 4]

因此,在此處的上下文中,整行採用輸入數組並計算每列中元素的最大長度。

的其餘代碼:

#initialize an empty list for the result 
    spacedLines = [] 

    #iterate over all lists 
    for array in arrays: 
     #initialize the line as an empty string 
     spacedLine = '' 
     #iterate over the array - enumerate returns position (i) and value 
     for i, field in enumerate(array): 
      #calculate the difference of the values length to the max length 
      #of all elements in the column 
      diff = verticalMaxLengths[i] - len(field) 
      #append the value, padded with diff times space to reach the 
      #max length, and a tab afterwards 
      spacedLine += field + ' ' * diff + '\t' 
     #append the line to the list of lines 
     spacedLines.append(spacedLine) 

    #join the list of lines with a newline and return 
    return '\n '.join(spacedLines)