在python中,按类的某个列表中的值对JSON转储进行排序

2024-06-13 10:56:02 发布

您现在位置:Python中文网/ 问答频道 /正文

我在订购JSON输出时遇到了一些问题。下面是Rolodex类,它包含两个列表条目和错误。现在输出的格式正确,如下所示,但是我对它的排序方式有问题。在

class Rolodex:
  def __init__(self):
    self.entries = []
    self.errors = []

class Entry:
  def __init__(self):
    color = None
    firstname = None
    lastname = None
    phonenumber = None
    zipcode = None

def encode_rolo(obj):
  if isinstance(obj, Entry):
    return obj.__dict__
  else:
    raise TypeError("Unserializable object {} of type {}".format(obj,type(obj)))

output.write(json.dumps(rolo.__dict__, sort_keys=True, indent=4, separators=(',', ': '), default=encode_rolo).encode('utf-8'))

以下是输出(截断):

^{pr2}$

如您所见,条目列表中的键的顺序非常好。但我希望能够按(姓,名)来排序条目。有什么办法吗json.dumps?在


Tags: selfnoneobj列表排序initdeftype
2条回答

如果我理解正确的话,这里的问题只是Rolodex.entries是按插入顺序排列的,而不是按名称排序。您可以将该属性设置为属性,而不是当前的常规属性,并让setter在每次插入时对该属性进行排序。方法如下:

class Rolodex(object):
    def __init__(self):
        self.errors = []
        self._entries = []

    @property
    def entries(self):
        self._entries.sort(key=lambda x: (x.lastname, x.firstname))
        return self._entries

其工作方式是,条目列表实际上存储在Rolodex._entries中,这是Rolodex实例的私有属性。现在,为了使Rolodex.entries按您的要求工作,我们将其设为property。这本质上意味着,您定义了一个方法,每次有东西试图访问这些条目时都应该运行该方法,当然包括json.dumps()。在这个特定的例子中,我们根据您的条件对类的私有条目列表进行排序,然后在每次有任何东西访问它时返回它。在

请注意,您必须使用您的类从object继承该功能(这就是您如何使用new-style classes,而且您应该养成始终从object继承的习惯)

还要注意,这个实现效率相当低,但它是我能想到的最可读、最容易理解的。您很可能不需要更好的性能,但是如果我在这一点上错了,您应该研究一下bisect模块,并使用它在您的列表中有效地插入,您可以在上面链接的属性文档中阅读setter方法。在

您可以在转换为json之前通过排序来实现它。在

例如:

entries.sort(key=lambda e: e['lastname']+e['firstname'])

相关问题 更多 >