列表中最长单词的长度

时间:2013-02-01 00:25:55

标签: python string performance list coding-style

获得最长单词长度的pythonic方法是什么:

len(max(words, key=len))

或者:

max(len(w) for w in words)

或者......别的什么? words是一个字符串列表。 我发现我需要经常这样做,并且在使用几个不同的样本大小计时之后,第一种方式似乎始终更快,尽管看起来表面效率较低(len被称为两次的冗余似乎并不重要 - 在这种形式的C代码中会发生更多吗?)。

6 个答案:

答案 0 :(得分:7)

虽然:

max(len(w) for w in words)

更容易“阅读” - 你得到了发电机的开销。

虽然:

len(max(words, key=len))

可以使用内置函数优化密钥,因为len通常是一个非常有效的字符串操作,会更快...

答案 1 :(得分:5)

我认为两者都可以,但我认为除非速度是max(len(w) for w in words)最具可读性的重要考虑因素。

当我看着它们的时候,花了我更长的时间来弄清楚len(max(words, key=len))正在做什么,而我还是错了,直到我想到它为止。代码应该立即显而易见,除非有充分的理由不这样做。

从其他帖子(以及我自己的测试)中可以清楚地看出,可读性较差的帖子更快。但这并不像他们中的任何一个都是狗慢。除非代码处于关键路径,否则不值得担心。

最终,我认为更具可读性更多是Pythonic。

顺便说一句,这是少数几个在同一任务中Python 2明显比Python 3快的情况之一。

答案 2 :(得分:3)

如果您将生成器表达式重写为map调用(或者,对于2.x,imap):

max(map(len, words))

......它实际上比关键版本快一点,而不是更慢。

python.org 64位3.3.0:

In [186]: words = ['now', 'is', 'the', 'winter', 'of', 'our', 'partyhat'] * 100
In [188]: %timeit max(len(w) for w in words)
%10000 loops, best of 3: 90.1 us per loop
In [189]: %timeit len(max(words, key=len))
10000 loops, best of 3: 57.3 us per loop
In [190]: %timeit max(map(len, words))
10000 loops, best of 3: 53.4 us per loop

Apple 64位2.7.2:

In [298]: words = ['now', 'is', 'the', 'winter', 'of', 'our', 'partyhat'] * 100
In [299]: %timeit max(len(w) for w in words)
10000 loops, best of 3: 99 us per loop
In [300]: %timeit len(max(words, key=len))
10000 loops, best of 3: 64.1 us per loop
In [301]: %timeit max(map(len, words))
10000 loops, best of 3: 67 us per loop
In [303]: %timeit max(itertools.imap(len, words))
10000 loops, best of 3: 63.4 us per loop

我认为它比key版本更加pythonic,原因与genexp相同。

它是否与genexp版本一样是pythonic是有争议的。有些人喜欢map / filter / reduce /等。有些人讨厌他们;我个人的感觉是,当你试图映射一个已经存在并且名字很好的函数时(也就是你不需要lambdapartial),{{1更好,但是YMMV(特别是如果你的名字是Guido)。

最后一点:

  

两次调用len的冗余似乎并不重要 - 在这种形式的C代码中会发生更多吗?

这样想:你已经打电话map N次了。相比之下,len次调用它几乎不可能产生任何影响,除非你有 巨大< / em> strings。

答案 3 :(得分:1)

我会说

len(max(x, key=len))

看起来相当不错,因为您使用内置(key)内置(max)的关键字参数(len)。所以基本上max(x, key=len)几乎可以得到答案。但是你的代码变体对我来说都不是特别不合理的。

答案 4 :(得分:0)

仅使用ipython %timeit

获取信息
In [150]: words
Out[150]: ['now', 'is', 'the', 'winter', 'of', 'our', 'partyhat']

In [148]: %timeit max(len(w) for w in words)
100000 loops, best of 3: 1.87 us per loop

In [149]: %timeit len(max(words, key=len))
1000000 loops, best of 3: 1.35 us per loop

更新了更多的单词来演示@ Omnifarious的观点/评论。

In [160]: words = map(string.rstrip, open('/usr/share/dict/words').readlines())

In [161]: len(words)
Out[161]: 235886

In [162]: %timeit max(len(w) for w in words)
10 loops, best of 3: 44 ms per loop

In [163]: %timeit len(max(words, key=len))
10 loops, best of 3: 25 ms per loop

答案 5 :(得分:-1)

我知道现在已经过了一年,但是无可奈何,我想出了这个:

&#39;&#39;&#39;编写一个函数find_longest_word(),它接受一个单词列表和 返回最长的长度。&#39;&#39;&#39;

a = ['mamao', 'abacate', 'pera', 'goiaba', 'uva', 'abacaxi', 'laranja', 'maca']

def find_longest_word(a):

    d = []
    for c in a:
        d.append(len(c))
        e = max(d)  #Try "min" :D
    for b in a:
        if len(b) == e:
            print "Length is %i for %s" %(len(b), b)