names.txt:
Ben
Lukasz
Filippe
Sam
Artur
代码:
full_names = (name.strip() for name in open('names.txt'))
length = ((name, len(name)) for name in full_names)
longest = max(length, key=lambda x: x[1] <= 5)
print(longest)
结果总是Ben
,但是,我想得到符合条件(x〈=5)的最长名称。Artur
如何修改max()以实现此输出?
如果删除条件并将其设置为:max(length, key=lambda x: x[1])
,它工作得很好。
5条答案
按热度按时间sg2wtvxw1#
If you want to filter the possible values, don't do that with the key, just filter with a generator expression and then pass that to
max
:You could define the
key
to achieve this in a roundabout way, e.g. with:so all lengths greater than the limit are treated as lengths of
-1
; this will misbehave when all the inputs fail the filter though (claiming a max exists when nothing passed the filter), so it's up to you if that's acceptable.In practice, it's kinda silly to decorate with the length when it can just be cheaply computed live, so:
is probably what I'd do.
yduiuuwa2#
您需要 filter
full_names
以仅保留长度为<= 5
的项,然后 * 查找最大值。请记住,您可以使用max
函数的key
参数将每个项Map到不同的值。例如:这里,
len
函数被调用用于filtered_names
中的每个元素,并且该函数的结果被用于计算max。您可以将这两行合并为一行,并通过使用生成器而不是创建
filtered_names
列表来保存一个循环如果你 * 真的 * 想使用你定义的
length
列表,你仍然需要过滤掉不满足条件的元素,然后 * 用length(在length
的每个元素的1
索引处)找到max
max
返回length
的item
,它在item[1]
处具有最大值。由于item
是一个同时包含名称和长度的元组,因此我们使用[0]
元素来获取最长的名称。在一行中:bnlyeluc3#
第一个问题是你实际上并没有比较名字的长度;您要比较名称长度是否小于或等于5。基本上,您要根据第二列从该表中取出最大值:
为了解决这个问题,你需要lambda表达式来返回实际的长度:
这将生成下表,并根据第二列(即Filippe)选择一个表:
如果只想考虑包含五个或更少字母的名称,可以进行以下过滤:
或者对于长度大于5的名称,让lambda返回零:
最后一种方法将产生以下结果,并再次根据第二列进行拾取:
ykejflvf4#
∮问题是
您面临的问题是,您对
max()
的key=
参数的作用有误解。它通过调用给定的函数为每个处理的项目分配一个键值,然后通过比较这些键值返回最大元素。在您的情况下,它分配:由于
bool
值只是int
s的一种特殊情况,因此键的等效表示形式为那么
max()
将返回具有最大键的元素"Ben"
,因为以下项都没有分配更大的键(另请参见:稳定分选)。解决方案
你想得到最长的项目,有五个或更少的字符。我们可以通过以下方式实现:
在这里我们使用了上面的事实,即
bool
s就是int
s,所以每个长度都乘以True
,即1
,如果它满足条件并因此不变,如果条件(〈=5)不满足,长度将乘以False
,即0
,因此为零。nnsrf1az5#
首先,你应该过滤序列,然后找到过滤后的序列中的最大值。