我找到了一个获取列表列表并返回字符串的函数。 但是我很难理解它究竟在做什么?请评论以下代码:
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)
答案 0 :(得分:2)
对map
的简短解释,使我免于丢弃以下代码并发表评论:
map
函数将第一个参数(通常是一个函数,但它也可以是一个类或任何其他可调用的东西)应用于第二个参数中的每个值,并返回结果列表。可以将其视为使用给定函数转换每个元素。使用两个参数,它的工作方式如下:
def map(fct, iterable): return [fct(x) for x in iterable]
与三个或更多参数一起使用时,map
假定第一个参数之后的所有参数都是可迭代的并且并行迭代它们,将每个iterable的第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。如上所述,用
多个参数,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)中返回的列表的所有元素上调用max(请记住元素是元组)。对于输入[(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)