def get_max(r, a, b):
""" Returns the maximum value in the form (index, value). """
return max([(x+a, r[a:b][x]) for x in xrange(len(r[a:b]))], key=lambda x:x[1])
有人可以解释这个列表理解的作用吗?
答案 0 :(得分:6)
为了提高效率,最好不要一遍又一遍地重复r
切片
chunk = r[a:b]
[(x+a, chunk[x]) for x in xrange(len(chunk))]
我认为它也使代码的含义更清晰(它不完全是Pythonic)
chunk = r[a:b]
[(i, j) for i, j in enumerate(chunk, a)]
哦,这是身份列表理解
list(enumerate(chunk, a))
所以,而不是所有的华夫饼干,你可以说
def get_max(r, a, b):
""" Returns the maximum value in the form (index, value). """
return max(enumerate(r[a:b], a), key=lambda x:x[1])
当@vonPetrushev试图在注释中解释时,你可以用itemgetter替换lambda函数。
from operator import itemgetter
def get_max(r, a, b):
""" Returns the maximum value in the form (index, value). """
return max(enumerate(r[a:b], a), key=itemgetter(1))
性能差异不大,itemgetter
版本更具描述性(只要您知道itemgetter
做了什么)
答案 1 :(得分:1)
让我们把它分解成碎片。
首先,这里只是listcomp:
[(x+a, r[a:b][x]) for x in xrange(len(r[a:b]))]
这相当于这个循环:
result=[]
for x in xrange(len(r[a:b])):
result.append((x+a, r[a:b][x]))
那么,每个部分做什么?
r[a:b]
是r
从索引a(包括)到b(不包括)的子序列。所以len(r[a:b])
几乎是一种说b-a
的奇特方式,但并不完全 - 因为b
可能超过序列的末尾,或者其中一个指数可能是负指数。而xrange(len(r[a:b]))
只是从0到该长度的所有数字(再次排他)。
现在,对于从0到该长度的每个数字x
,我们创建一个元组(x+a, r[a:b][x])
。
让我们来看一个例子:
>>> r = ['a', 'b', 'c', 'd', 'e', 'f']
>>> a = 2
>>> b = 4
>>> r[a:b]
['c', 'd']
>>> len(r[a:b])
2
>>> list(xrange(len(r[a:b])))
[0, 1]
>>> x=0
>>> (x+a, r[a:b][x])
(2, 'c')
>>> x = 1
>>> (x+a, r[a:b][x])
(3, 'd')
因此,正如您所看到的,它正在为a
到b
的索引创建一个(索引,值)列表,如下所示:
[(2, 'c'), (3, 'd')]
编写相同内容的更好方法是:
>>> list(enumerate(r))[a:b]
[(2, 'c'), (3, 'd')]
......或......
>>> list(enumerate(r[a:b], a)
[(2, 'c'), (3, 'd')]
答案 2 :(得分:1)
r
是一个序列,a
是起始索引,b
是结束索引。列表理解将给出(index, r[index])
元组的列表a <= index < b
。 max()
调用将返回具有最大值的元组(元组中的第二项)。