7

最長の単語の長さを取得するためのよりPython的な方法は何ですか?

len(max(words, key=len))

または:

max(len(w) for w in words)

または、他の何か? words文字列のリストです。私はこれを頻繁に行う必要があることに気づき、いくつかの異なるサンプルサイズでタイミングをとった後、最初の方法は、額面通りの効率が低いように見えますが、一貫して高速であるようです(len2回呼び出される冗長性は重要ではないようです-より多くのことが起こりますこの形式のCコード?)。

4

6 に答える 6

7

それでも:

max(len(w) for w in words)

一種の「読み取り」が簡単になります。ジェネレーターのオーバーヘッドがあります。

その間:

len(max(words, key=len))

ビルトインを使用してキーを最適化することができ、len通常は文字列に対して非常に効率的な操作であるため、より高速になります...

于 2013-02-01T00:30:56.853 に答える
5

どちらも大丈夫だと思いますが、速度が大きな考慮事項でない限りmax(len(w) for w in words)、最も読みやすいと思います。

それらを見ていると、何をしているのか理解するのに時間がかかり、len(max(words, key=len))もっと考えるまではまだ間違っていました。コードは、そうでない正当な理由がない限り、すぐに明らかになるはずです。

他の投稿(および私自身のテスト)から、読みにくいものの方が速いことは明らかです。しかし、どちらも犬が遅いというわけではありません。また、コードがクリティカルパス上にない限り、心配する価値はありません。

最終的には、読みやすくなるほどPythonicになると思います。

余談ですが、これは、同じタスクでPython2がPython3よりも著しく高速である数少ないケースの1つです。

于 2013-02-01T00:42:26.043 に答える
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

keygenexpと同じ理由で、バージョンよりもpythonicだと思います。

それがgenexpバージョンと同じくらいpythonicであるかどうかは議論の余地があります。map一部の人々は///などを愛していますfilterreduce嫌いな人もいます。私の個人的な感想は、すでに存在し、素敵な名前(つまり、必要のないもの)を持つ関数をマップしようとしているときは、lambdaよりpartial良いmapですが、YMMV(特にあなたの名前がGuidoの場合) 。

最後にもう1つ:

lenが2回呼び出される冗長性は問題ではないようですが、この形式のCコードではさらに多くのことが起こりますか?

このように考えてください:あなたはすでにlenN回電話をかけています。代わりにそれを回と呼ぶことは、あなたが数回の巨大文字列を持っていない限り、あなたが何回もしなければならないことN+1と比較して、違いを生む可能性はほとんどありません。N

于 2013-02-01T00:51:06.067 に答える
1

私は言うだろう

len(max(x, key=len))

組み込み( )と組み込み( key)のキーワード引数()を使用するため、非常に見栄えがします。つまり、基本的にはほとんど答えが得られます。しかし、あなたのコードバリアントはどれも私には特に非Python的に見えません。maxlenmax(x, key=len)

于 2013-02-01T00:28:03.683 に答える
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
于 2013-02-01T00:35:34.043 に答える
-1

1年が経ちましたが、それでも、私はこれを思いつきました。

'''単語のリストを取得し、最長の単語の長さを返す関数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)
于 2014-08-30T03:28:48.123 に答える