在python中,按类的一个列表中的值对JSON转储进行排序
我在订购JSON输出时遇到了一些麻烦。下面是Rolodex类,它包含两个列表条目和错误。现在输出已正确格式化,如下所示,但我对它的排序方式有问题在python中,按类的一个列表中的值对JSON转储进行排序,python,json,dictionary,Python,Json,Dictionary,我在订购JSON输出时遇到了一些麻烦。下面是Rolodex类,它包含两个列表条目和错误。现在输出已正确格式化,如下所示,但我对它的排序方式有问题 class Rolodex: def __init__(self): self.entries = [] self.errors = [] class Entry: def __init__(self): color = None firstname = None lastname = None
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'))
以下是输出(已截断):
如您所见,条目列表中的键排列得很好。但是我希望能够按照(Lastname,Firstname)对条目进行排序。使用json.dumps有什么方法可以做到这一点吗?您可以在转换为json之前通过排序来实现 例如:
entries.sort(key=lambda e: e['lastname']+e['firstname'])
如果我理解正确,这里的问题只是
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实例的私有属性中。现在,为了使Rolodex.entries
按您的要求工作,我们将其设置为一个。这本质上意味着,您定义了一个方法,每当有东西试图访问条目时都应该运行该方法,当然包括json.dumps()
。在这个特定的例子中,我们根据您的条件对类的私有条目列表进行排序,然后在每次有任何东西访问它时返回该列表
请注意,您必须使用类继承对象
,才能使用此功能(这就是您的使用方式,无论如何,您应该养成始终从对象
继承的习惯。)
还要注意,这个实现效率很低,但却是我能想到的最可读、最容易理解的实现。您很可能也不需要更好的性能,但如果我在这一点上错了,您应该研究该模块,并使用该模块在列表中进行有效插入,使用setter方法,您可以在我上面链接的属性文档中了解该方法。您是否尝试在json.dumps
之前对条目进行排序?这很有效。我真傻。添加的代码:rolo.entries=sorted(rolo.entries,key=attrgetter('lastname','firstname'))
或者:rolo.entries=sorted(rolo.entries,key=attrgetter('lastname','firstname'))
感谢您的帮助。出于某种原因,它没有点击我可以确保列表在转储到json之前已排序。
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