什么是得到最长的单词的长度更Python的方式:长度最长的单词的
len(max(words, key=len))
或者:
max(len(w) for w in words)
或..别的东西? words
是一个字符串列表。 我发现我需要经常这样做,在计算好几个不同的样本数后,第一种方式似乎始终快一些,尽管在面值方面看起来效率较低(冗余的len
被称为两次似乎无关紧要 - 更多在这种形式的C代码中发生?)。
什么是得到最长的单词的长度更Python的方式:长度最长的单词的
len(max(words, key=len))
或者:
max(len(w) for w in words)
或..别的东西? words
是一个字符串列表。 我发现我需要经常这样做,在计算好几个不同的样本数后,第一种方式似乎始终快一些,尽管在面值方面看起来效率较低(冗余的len
被称为两次似乎无关紧要 - 更多在这种形式的C代码中发生?)。
我觉得都是正常的,但我认为,除非速度是一大考虑到max(len(w) for w in words)
是最可读的。
当我看着它们时,我花了更长的时间才弄清楚len(max(words, key=len))
在做什么,而且在我考虑更多之前我仍然是错误的。代码应该立即显而易见,除非有充分的理由不这样做。
从其他帖子(以及我自己的测试)可以看出,可读性较差的文章更快。但是,这不是他们中的任何一个都很慢。除非代码处于关键路径,否则不值得担心。
最终,我认为更可读的是更Pythonic。另外,这是少数情况下Python 2比Python 3在同一任务中速度明显更快的情况之一。
在我的测试中,3.3.0为我能想到的每个版本都打2.7.2。 (请参阅我的答案,以明显的。) – abarnert
更新:实际上,如果我在32位模式下运行它们,则3.3.0显着较慢。但是,至少在Mac电脑上,几乎所有的东西在32位3.2或3.3中似乎都很慢,所以我不认为这种情况有任何特定的含义。 – abarnert
@abarnert:有趣。我在Linux系统上以64位模式运行它们。一个是Python 2.7.3,另一个是3.3.0。我使用'/ usr/share/dict/words'作为单词列表。我的速度是88ms vs 66ms。也许这是我选择的一个长长的单词列表,它有所不同。 – Omnifarious
虽然:
max(len(w) for w in words)
做样的“阅读”更容易 - 你有一台发电机的开销。
虽然:
len(max(words, key=len))
可以优化掉使用内建的关键,自len
通常是一个非常有效的运算字符串,将是更快......
这就是说 - 我不能说哪个更“Pythonic” - 我喜欢这两种,但对于不熟悉'key'的'max'使用的人来说,前者可能会立刻变得更加可靠 –
只为信息使用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
作为列表时间越长,差异越大。 – Omnifarious
如果您将生成器表达式重写为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
苹果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
版本更Python,出于同样的原因genexp是。
这是值得争议的是它是pyxonic作为genexp版本。有人喜欢map
/filter
/reduce
/etc;有些讨厌他们;我个人的感觉是,当你试图映射一个已经存在并且名字很好的函数(也就是说,你不需要lambda
或partial
),map
更好,但是YMMV(尤其是如果你的名字是Guido)。
最后一点:
LEN被调用两次冗余似乎并不重要 - 没有更多的发生在C代码以这种形式?
想想这样:你已经拨打了len
N次。调用它N+1
次反而几乎不可能有所作为,相比之下你要做的任何事情N
次,除非你有一个微小的数巨大的字符串。
'max(map (len,words))'也是非常可读和明显的。所以它得到我的投票。 – Omnifarious
@Omnifarious:它对我来说是可读的,对你而言是显而易见的,但对你而言......但也许对每个人都不是。我添加了一个关于这个的段落。 – abarnert
我知道它已经现在开始的一年,但neverthless,我想出了这个:
“”“写一个函数find_longest_word(),它的单词和 返回最长的一个的长度的名单。” ''
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)
@isedev那会给这个词,而不是词 –
个人而言,我更喜欢后者的长度,看起来更漂亮 – Wolph
''LEN(MAX(也就是说,键= LEN))''好因为它作为一个*哦,我忘了''max''把钥匙作为参数。*提醒湿件。 – sotapme