tes*_*ter 13 python sorting recursion ordereddictionary
Say orig是一个OrderedDict包含普通字符串:字符串键值对的,但有时值可能是另一个嵌套的OrderedDict.
我想orig按键,按字母顺序(升序)排序,并以递归方式进行排序.
规则:
需要协助sorted算法:
import string
from random import choice
orig = OrderedDict((
('a', choice(string.digits)),
('b', choice(string.digits)),
('c', choice(string.digits)),
('special', OrderedDict((
('a', choice(string.digits)),
('b', choice(string.digits)),
('c', choice(string.digits)),
)))
))
sorted_copy = OrderedDict(sorted(orig.iteritems(), ...))
self.assertEqual(orig, sorted_copy)
Run Code Online (Sandbox Code Playgroud)
acu*_*ner 18
编辑:对于python 3.6+,@ pelson的答案更好
就像是:
def sortOD(od):
res = OrderedDict()
for k, v in sorted(od.items()):
if isinstance(v, dict):
res[k] = sortOD(v)
else:
res[k] = v
return res
Run Code Online (Sandbox Code Playgroud)
现在可以在python3.6 +中简化@ acushner的解决方案,因为词典现在保留了它们的插入顺序.
鉴于我们现在可以使用标准字典,代码现在看起来像:
def order_dict(dictionary):
result = {}
for k, v in sorted(dictionary.items()):
if isinstance(v, dict):
result[k] = order_dict(v)
else:
result[k] = v
return result
Run Code Online (Sandbox Code Playgroud)
因为我们可以使用标准词典,所以我们也可以使用标准字典理解,因此代码归结为:
def order_dict(dictionary):
return {k: order_dict(v) if isinstance(v, dict) else v
for k, v in sorted(dictionary.items())}
Run Code Online (Sandbox Code Playgroud)
有关python有序字典实现的详细信息,另请参阅https://mail.python.org/pipermail/python-dev/2016-September/146327.html.此外,声明这将是python 3.7的语言功能:https://mail.python.org/pipermail/python-dev/2017-December/151283.html
我在获取稳定对象时遇到了一个非常相似的问题,这样我就可以获得稳定的散列,除了我的对象混合了列表和字典,所以我必须先对所有字典进行排序,深度优先,然后对列表进行排序。这扩展了@acushner的回答:
def deep_sort(obj):
if isinstance(obj, dict):
obj = OrderedDict(sorted(obj.items()))
for k, v in obj.items():
if isinstance(v, dict) or isinstance(v, list):
obj[k] = deep_sort(v)
if isinstance(obj, list):
for i, v in enumerate(obj):
if isinstance(v, dict) or isinstance(v, list):
obj[i] = deep_sort(v)
obj = sorted(obj, key=lambda x: json.dumps(x))
return obj
Run Code Online (Sandbox Code Playgroud)
顺便说一句,如果您发现自己的对象中有需要排序的类,您可以对jsonpickle.dumps()它们进行排序,然后是json.loads()它们,然后是deep_sort()它们。如果它的事项,那么你可以随时json.dumps()和jsonpickle.loads()要回你开始的地方,除了进行排序(当然,只有在Python分类3.6+)。对于稳定散列的情况,虽然没有必要。
小智 5
与@ acushner的解决方案非常相似,但基于类:
from collections import OrderedDict
class SortedDict(OrderedDict):
def __init__(self, **kwargs):
super(SortedDict, self).__init__()
for key, value in sorted(kwargs.items()):
if isinstance(value, dict):
self[key] = SortedDict(**value)
else:
self[key] = value
Run Code Online (Sandbox Code Playgroud)
用法:
sorted_dict = SortedDict(**unsorted_dict)
Run Code Online (Sandbox Code Playgroud)