在列表中对元组的两个元素进行排序,忽略大小写,以便字典的键正确排列

Sort both elements of a tuple, ignoring case, within a list, so that the keys of a dictionary line up correctly

我正在迭代相同 class 的两个实例以检查是否相等。 class 的这两个实例是通过不同的方式创建的:一个来自 pickle,另一个来自 json 文档。

我正在遍历这些对象的属性,以检查是否相等,但是,字典中的键并不总是对齐,因此无法正确比较它们。所以我尝试对这些元组进行排序,但由于区分大小写,我无法始终从这两个对象中获取相同的键。

一次尝试让我在左侧排序:

def __eq__(self, other):
    for (self_key, other_key) in sorted(
         zip(self.__dict__, other.__dict__),
         key=lambda element: (element[0].lower(), element[1].lower())):            
            print self_key, " ", other_key
      ....

输出

alpha   VAR_THRESH
chunksize   VAR_MAXITER
decay   decay
....

如果我明确地只制作右侧 lower() 我会得到相反的结果:例如

  ....
   key=lambda element: (element[0], element[1].lower())):
  ....

左侧未按低位排序。

VAR_MAXITER   alpha
VAR_THRESH   chunksize
alpha   VAR_THRESH
chunksize   VAR_MAXITER
decay   decay

如果我在两个元素上都省略 .lower(),我得到第二个例子。

我怎样才能确保正确的键始终排列?或者换句话说,如何按元组中的两个值排序,忽略大小写,以便它们始终排成一行?

zip() 将为您提供每个可迭代对象中的相应元素。排序 zip() returns 对你没有帮助。在将它们传递给 zip() 之前,您需要对键进行排序。不过,那确实不是您想要的。只需这样做:

def __eq__(self, other):
    if self.__dict__.viewkeys() != other_keys.__dict__.viewkeys(): # .keys() in Python 3
        return False
    return all(other.__dict__[key] == self.__dict__[key] for key in self.__dict__)

简单的方法是这样的:

def __eq__(self, other):
    self.__dict__ == other.__dict__

但是您可以更轻松地更改第一个以定义什么才算等价。

以下(由 Padraic Cunningham 提出)更接近您的要求:

def __eq__(self, other):
    return all(
        sorted(v) == sorted(self.__dict__[key])
            if isinstance(v, np.array)
        else self.__dict__[key] == v
        for key, v in other.__dict__.iteritems()
    )

这是一个捷径:

def __eq__(self, other):
    for key, v in other.__dict__.iteritems(): # .items() in Python 3
        if isinstance(v, np.array) and sorted(v) != sorted(self.__dict__[key]):
                return False
        elif self.__dict__[key] != v:
            return False
    return True

字典本质上是无序的。将键强制为适合您特定定义的某种顺序当然是可能的,但也完全没有必要。您可以改为尝试这样的操作:

def __eq__(self, other):

  # first, check to make sure that the two sets of keys are identical
  if self.__dict__.keys() != other.__dict__.keys():
    return False

  # now that we know the dictionaries have identical key sets, check
  # for equality of values.
  for key in self.__dict__.keys():
    if self.__dict__[key] != other.__dict__[key]:
      return False

  # if everything worked, then the dictionaries are identical!
  return True