2012-04-02 14 views
3

operator.itemgetterオブジェクトには__eq__が定義されていないことがわかりました。そのため、比較のデフォルトはIDの確認(is)です。itemgetterオブジェクトを比較する

2つのitemgetterインスタンスを初期化引数リストが等しいと見なされるたびに等しいと定義することに不利な点はありますか?

このような比較の1つの使用例です。ソートを定義するためにキー関数が必要なコンストラクタを持つソートされたデータ構造体を定義するとします。例えば、assertステートメントの中で、2つのそのようなデータ構造が同じキー機能を持っているかどうか、またはそれらが安全にマージできるかどうかを確認するなどをチェックしたいとします。

2つの重要な機能がitemgetter('id')である場合に、その質問に肯定的に答えることができればうれしいです。しかし、現在、itemgetter('id') == itemgetter('id')Falseと評価されます。

+0

私は、これは参考になるかが表示されない...そのCで 'itemgetter'が定義されているのを見て、' __getitem__'をオーバーライドしてクラスをハックし、2つのgetterを実行して同じ項目にアクセスしたかどうかを確認できます。これはエレガントで速い解決策ではありませんが、私はあなたがより良いやり方をすることはできません。 @ NiklasB。 –

+0

私はこれの動機づけを提供するために質問を更新しました。 – max

+0

この場合、 'lambda'式を使用します。 – satoru

答えて

4

ニクラスの答えは非常に賢いですが、itemgetterとして強力な条件を必要とする複数の引数

from collections import defaultdict 
from operator import itemgetter 
from itertools import count 

def cmp_getters(ig1, ig2): 
    if any(not isinstance(x, itemgetter) for x in (ig1, ig2)): 
     return False 
    d1 = defaultdict(count().next) 
    d2 = defaultdict(count().next) 
    ig1(d1)         # populate d1 as a sideeffect 
    ig2(d2)         # populate d2 as a sideeffect 
    return d1==d2 

にいくつかのテストケースを取ることができ

>>> cmp_getters(itemgetter('foo'), itemgetter('bar')) 
False 
>>> cmp_getters(itemgetter('foo'), itemgetter('bar','foo')) 
False 
>>> cmp_getters(itemgetter('foo','bar'), itemgetter('bar','foo')) 
False 
>>> cmp_getters(itemgetter('bar','foo'), itemgetter('bar','foo')) 
True 
+0

これは完全に機能しますが、 'class itemgetter'がこの機能を実装するべきかどうかは疑問です。(インスタンスの内部状態に依存できるので、明らかに簡単です。 – max

+0

@maxでは、itemgetterクラスはCで実装されているので、実際にその機能を追加することはできません。 –

+0

FYI PEPはこのような小さなものには必要ありませんが、pepを提案できます。 –

0

itemgetterは呼び出し可能です。 は、コールバックを比較したくありません。正しい?同じ引数を渡しても、返される呼び出し可能IDは同じではないためです。一方

def fun(a): 
    def bar(b): 
     return a*b 
    return bar 

a = fun(10) 
print id(a(10)) 

a = fun(10) 
print id(a(10)) 

あなたは基礎となるオブジェクトにアクセスするためのアクセサとして呼び出し可能itemgetterを使用する場合、そのオブジェクトの比較は、比較 を実行するために使用されることはSorting Howto using the operating module functionsに例示されています。

+2

私は* callableを比較するつもりはなかったが、私は 'itemgetter'インスタンス(実際には呼び出し可能)だけを比較しようとしていた! 'itemgetter'のセマンティクスのため、初期化引数に基づいて比較するのが安全であるようです。私は何か不足していますか? – max

関連する問題