该key
参数告诉什么来min
确定最小值。
如果没有key
参数,min
将任何给定的整个元组与其他元组进行比较,然后首先比较元组中的第一个元素。为输入序列中的每个元素调用该key
函数,并且最小元素仅由该键的返回值确定。lambda k: k[1]
返回元组中的第二个元素。
比较以下两种结果:
>>> example = [(5, 1), (4, 2), (3, 3), (2, 4), (1, 5)]
>>> min(example)
(1, 5)
>>> min(example, key=lambda element: element[1])
(5, 1)
在第一个示例中,没有key
提供函数并按min()
原样比较每个元组,在第二个示例中,min()
仅查看key()
函数返回的内容,因此选择不同的元素作为最小值。
您可以使用该关键功能真正过火:
>>> min(example, key=lambda element: (element[0] / element[1]) + element[1])
(4, 2)
usingstr
并不是真正需要的,整个表达式过于冗长;您可以将其简化为:
i = min((x for x in aList if x[2] == 1), key=lambda k: k[1])
或使用operator.itemgetter
:
from operater import itemgetter
i = min((x for x in aList if x[2] == 1), key=itemgetter(1))
要比较相邻对,您需要一个itertools
辅助函数:
from itertools import tee, izip
def pairwise(iterable):
"s -> (s0,s1), (s1,s2), (s2, s3), ..."
a, b = tee(iterable)
next(b, None)
return izip(a, b)
然后使用以下方法将“最后一个元素为 1”标准移动到过滤器更容易itertools.ifilter
:
from itertools import ifilter
last_is_one = ifilter(lambda x: x[2] == 1, aList)
paired = pairwise(last_is_one)
现在我们可以做真正的工作了;对于每对相邻列表,找到第二个元素总和最低的对,然后从该对中找到第二个元素的最低值:
# find minimum pair by second elements summed
minpair = min(paired, key=lambda pair: pair[0][1] + pair[1][1])
minimum = min(minpair, key=itemgetter(1))
总而言之,过滤的责任留给函数的调用者:
from operater import itemgetter
from itertools import tee, izip
def pairwise(iterable):
"s -> (s0,s1), (s1,s2), (s2, s3), ..."
a, b = tee(iterable)
next(b, None)
return izip(a, b)
def neighbouring_minimum(iterable):
paired = pairwise(iterable)
# find minimum pair by second elements summed
minpair = min(paired, key=lambda pair: pair[0][1] + pair[1][1])
return min(minpair, key=itemgetter(1))
对于您提供的示例输入:
>>> from itertools import ifilter
>>> aList = [[10564, 15, 1], [10564, 13, 1], [10589, 18, 1], [10637, 39, 1], [10662, 38, 1], [10837, 45, 1], [3, 17, 13], [7, 21, 13], [46, 1, 13]]
>>> filtered = ifilter(lambda x: x[2] == 1, aList)
>>> neighbouring_minimum(filtered)
[10564, 13, 1]
您甚至可以将最小值的标准移至单独的关键参数:
def neighbouring_minimum(iterable, key=None):
if key is None:
# default to the element itself
key = lambda x: x
paired = pairwise(iterable)
# find minimum pair by key summed
minpair = min(paired, key=lambda pair: sum(map(key, pair)))
return min(minpair, key=key)
neighbouring_minimum(ifilter(lambda x: x[2] == 1, aList), key=itemgetter(1))