2012-07-02 11 views
24

ここで、より一般的な質問があります:In what situation should the built-in operator module be used in python?[x]の代わりにoperator.itemgetter(x)を使用する理由は何ですか?

はトップの答えはoperator.itemgetter(x)lambda a: a[x]よりも、おそらく、より「すっきり」であると主張しています。私はその反対が本当であると感じます。

パフォーマンスなどの他の利点はありますか?

+0

そのちょうど明確あなたの書き込みフィルタまたはラムダ –

+0

上のファイル名を指定して実行しますが、ラムダを使用する他の開発者とのチームで作業している場合、あなたはラムダを使用する必要があります:) – astynax

+0

尋ねたように、私は推測しますあなたの質問に対する正しい答えは「決して」ではありません。しかし実際には、** [**]を使うことができない状況**について知りたかったのです。 –

答えて

17

コードが内部のループに詰まっていて、実際にはパフォーマンスの問題でない限り、パフォーマンスについて心配する必要はありません。代わりに、あなたの意図を最もよく表すコードを使用してください。ラムダを好む人もいますし、itemgetterのような人もいます。時にはそれは味の問題です。

itemgetterは、たとえば、一度に多数の要素を取得する必要がある場合など、より強力です。たとえば:

lambda s: (s[1], s[3], s[5]) 
+5

"itemgetterはより強力です"?それは後ろ向きです。私はitemgetterでできないラムダでたくさんのことをすることができます。よりコンパクトにすることができます。 – DSM

+0

@DSM:彼は柔軟性とは対照的にCのパフォーマンスに関して強力だと思っています。 – jdi

+6

ネッドは、質問者が質問したとおりの[]演算子よりも強力だと確信しています。明らかに、ラムダ内の任意のPythonコードよりも強力です。 –

9

パフォーマンス:

operator.itemgetter(1,3,5) 

は同じです。それは大きな違いを生むことができます。適切な状況では、itemgetterを使用して、Cレベルで一連の作業を行うことができます。

は、私が明確であるものの主張は本当にあなたが最も頻繁に使用すると

11

は、いくつかの状況ではメリットがあり、非常に主観的であろうに依存だと思い、ここに良い例です。また、より高速なすべての操作がC側に保持されているようでありながら、それはすべてが明確になるため

>>> data = [('a',3),('b',2),('c',1)] 
>>> from operator import itemgetter 
>>> sorted(data, key=itemgetter(1)) 
[('c', 1), ('b', 2), ('a', 3)] 

itemgetterの使用は素晴らしいです。 lambdaを使用して

>>> sorted(data, key=lambda x:x[1]) 
[('c', 1), ('b', 2), ('a', 3)] 

はそれも遅く、あなたがする必要がある場合を除きlambdaを使用しないことが好ましい、として明確ではありません。例えば。リスト内包表記は、lambdamapを使用するよりも優先されます。

+11

個人的に私はこれらの場合にラムダをより明確に見出します。 "明確な"ものは客観的な主張ではない。 'itemgetter'とfriendsは、概念的に名前のついたラムダだけではありません。おそらくラムダを知っている人は(ラムダを知っていてすでに知っているので)、ラムダを知っているからです。ラムダは思考に慣れていない人は 'itemgetter'を見つけやすくなりますが、ラムダは"何を意味するのか "、" itemgetter "は追加の名前を記憶する必要があります)。 – Ben

7

プログラマーの中にはラムダを理解して使用するものもありますが、コンピューターサイエンスを取っていないプログラマーの集まりがあり、概念上明確ではありません。それらのプログラマーのために、itemgetter()あなたの意思を明確にすることができます。 (私はラムダを書いていないし、コード内にあるものを見るたびに、何が起こっているのかを理解し、コードを理解するのに少し時間がかかる)。

他のコンピュータサイエンスの専門家のためのコーディングがより快適であれば、ラムダを使用してください。しかし、より広いオーディエンスをコーディングする場合は、itemgetter()を使用することをおすすめします。

1

lambdaは、既存の応答に追加するには、itemgetterを削除することができます。これは、関数を保存する必要がある場合や、プロセス間で(通常は大きなオブジェクトの一部として)渡す必要がある場合に重要です。次の例では、itemgetterlambdaに置き換えると、PicklingErrorとなります。性能が述べたように

from operator import itemgetter 

def sort_by_key(sequence, key): 
    return sorted(sequence, key=key) 

if __name__ == "__main__": 
    from multiprocessing import Pool 

    items = [([(1,2),(4,1)], itemgetter(1)), 
      ([(5,3),(2,7)], itemgetter(0))] 

    with Pool(5) as p: 
     result = p.starmap(sort_by_key, items) 
    print(result) 
1

、私は両方の方法operator.itemgetterlambdaを比較しました、小さなリストについては、それがoperator.itemgetter10%でラムダよりも優れていることが判明しました。私は個人的にはitemgetterメソッドが好きです。ソートの際に主に使用するので、私のキーワードのようになりました。

import operator 
import timeit 

x = [[12, 'tall', 'blue', 1], 
[2, 'short', 'red', 9], 
[4, 'tall', 'blue', 13]] 


def sortOperator(): 
    x.sort(key=operator.itemgetter(1, 2)) 

def sortLambda(): 
    x.sort(key=lambda x:(x[1], x[2])) 


if __name__ == "__main__": 
    print(timeit.timeit(stmt="sortOperator()", setup="from __main__ import sortOperator", number=10**7)) 
    print(timeit.timeit(stmt="sortLambda()", setup="from __main__ import sortLambda", number=10**7))  

>>Tuple: 9.79s, Single: 8.835s 
>>Tuple: 11.12s, Single: 9.26s 

のPython 3.6