【问题标题】:comparing itemgetter objects比较 itemgetter 对象
【发布时间】:2012-04-15 18:00:26
【问题描述】:

我注意到 operator.itemgetter 对象没有定义 __eq__,因此它们的比较默认为检查身份 (is)。

当两个itemgetter 实例的初始化参数列表比较相等时,将它们定义为相等有什么缺点吗?

这是这种比较的一个用例。假设您定义了一个排序的数据结构,其构造函数需要一个键函数来定义排序。假设您要检查两个这样的数据结构是否具有相同的关键功能(例如,在 assert 语句中;或验证它们是否可以安全合并;等等)。

如果我们能在两个关键函数是itemgetter('id') 时肯定地回答这个问题,那就太好了。但目前,itemgetter('id') == itemgetter('id') 将评估为 False

【问题讨论】:

  • 我看不出这会有什么帮助...也就是说,看到 itemgetter 是在 C 中定义的,您可以将一个覆盖 __getitem__ 的类组合在一起,然后运行这两个getter 以检查是否访问了相同的项目。这不是一个优雅或快速的解决方案,但我看不出你可以做得更好。
  • @NiklasB。我更新了这个问题以提供动机。
  • 在这种情况下我会使用lambda 表达式。
  • @NiklasB。我不这么认为,Python中的很多内置函数都接受key作为函数,如果新的key参数也是函数就更容易理解了。
  • @Satoru:我不明白你的意思。

标签: python python-3.x operators


【解决方案1】:

Niklas 的回答非常聪明,但需要一个更强的条件,因为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

【讨论】:

  • 这会很完美,但我实际上想知道class itemgetter 是否应该实现这个功能(这显然会容易得多,因为它可以依赖于实例的内部状态)。跨度>
  • @max,itemgetter 类是用 C 实现的,所以你不能真正添加​​这个功能,不过你可以提出一个鼓舞人心的建议
  • 这么小的事情不需要仅供参考。
  • +1,使用count 来检查getter 的应用顺序非常聪明。我什至不知道itemgetter 可以接受多个参数! @max:我已经在我对这个问题的第一条评论中提到了这个问题无法优雅地解决。
【解决方案2】:

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 callable 作为访问器来访问底层对象时,该对象的比较将用于执行比较 它在Sorting Howto using the operating module functions 中进行了说明。

【讨论】:

  • 我不是要比较 any 可调用的,我的意思是只比较 itemgetter 实例(它们确实是可调用的)!由于itemgetter 的语义,根据初始化参数比较它们似乎是安全的。我错过了什么吗?
猜你喜欢
  • 2013-11-01
  • 2011-07-09
  • 2011-09-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多