Python 使用预定义的顺序对 Dict 进行排序
Python order Dict with a pre-defined order
收到一个字典和return一个新的有序字典
A json return来自 api:
{
'host': '192.168.0.1',
'name': 'my_new_name',
'port': 443,
'something_more': 'hello'
}
目标:
{
'name': 'my_new_name',
'something_more': 'hello',
'host': '192.168.0.1',
'port': 443
}
有什么方法可以定义键的顺序?
例如要在目标上实现此顺序:
key_order = ('name', 'something_more', 'host', 'port')
谢谢
Ordered Dictionary 是你需要的东西我的朋友。]
from collections import OrderedDict
d = OrderedDict([
('name', 'my_new_name'),
('something_more', 'hello'),
('host', '192.168.0.1'),
('port', 443)
])
编辑:这仅适用于 Python 3.6+。还向 OrderedDict
提供元组列表而不是字典来维护键值对的顺序。
如果您使用的是 Python 3.7 或更高版本*,您可以指定字典中项目的顺序,因为插入顺序会保留。创建一个新字典并按您喜欢的顺序插入项目:
def reorder_items(d, keys):
d = d.copy() #we're going to destructively modify d, so make a copy first
result = {}
for key in keys:
if key in d:
result[key] = d.pop(key)
#the user might not have supplied all the keys belonging to d,
#so insert anything we haven't touched yet
result.update(d)
return result
d = {
'host': '192.168.0.1',
'name': 'my_new_name',
'port': 443,
'something_more': 'hello'
}
desired_key_order = ('name', 'something_more', 'host', 'port')
goal = reorder_items(d, desired_key_order)
print(goal)
结果:
{'name': 'my_new_name', 'something_more': 'hello', 'host': '192.168.0.1', 'port': 443}
(*您也可以在 CPython 3.6 中执行此操作,但这是不应依赖的实现细节)
在 3.7 之前,您无法直接控制字典中项目的排序方式。但是您可以使用 collections.OrderedDict
类型。使用前面代码块中的函数,将 result = {}
切换为 result = collections.OrderedDict()
.
更简洁(尽管有点不透明)的方法是:
result = {key:d[key] for category in (desired_key_order, d.keys()) for key in category if key in d}
#or, for versions prior to 3.7,
result = collections.OrderedDict((key, d[key]) for category in (desired_key_order, d.keys()) for key in category if key in d)
这利用了字典理解和 OrderedDict 可以用重复的键构造的事实,同时保持与每个键的第一次出现相关的顺序。
这仍然比 jpp 的解决方案长一点,因为它试图变得更容错。即使 d
包含 desired_key_order
不包含的键,它也能工作,反之亦然。未指定顺序的项目将出现在具有指定顺序的项目之后的结果中。
如果您使用的是 Python <3.7,OrderedDict
会保留项目的顺序:
from collections import OrderedDict
d = OrderedDict([
('name', 'my_new_name'),
('something_more', 'hello'),
('host', '192.168.0.1'),
('port', 443)
])
# OrderedDict([('name', 'my_new_name'), ('something_more', 'hello'), ('host', '192.168.0.1'), ('port', 443)])
您可以使用列表理解将元组列表提供给 collections.OrderedDict
:
from collections import OrderedDict
d = {'host': '192.168.0.1', 'name': 'my_new_name',
'port': 443, 'something_more': 'hello'}
key_order = ('name', 'something_more', 'host', 'port')
res = OrderedDict([(k, d[k]) for k in key_order])
OrderedDict([('name', 'my_new_name'),
('something_more', 'hello'),
('host', '192.168.0.1'),
('port', 443)])
适用于 Python 2.x 以后。对于 Python 3.7+,您可以依赖插入顺序并使用常规字典。
收到一个字典和return一个新的有序字典
A json return来自 api:
{
'host': '192.168.0.1',
'name': 'my_new_name',
'port': 443,
'something_more': 'hello'
}
目标:
{
'name': 'my_new_name',
'something_more': 'hello',
'host': '192.168.0.1',
'port': 443
}
有什么方法可以定义键的顺序?
例如要在目标上实现此顺序:
key_order = ('name', 'something_more', 'host', 'port')
谢谢
Ordered Dictionary 是你需要的东西我的朋友。]
from collections import OrderedDict
d = OrderedDict([
('name', 'my_new_name'),
('something_more', 'hello'),
('host', '192.168.0.1'),
('port', 443)
])
编辑:这仅适用于 Python 3.6+。还向 OrderedDict
提供元组列表而不是字典来维护键值对的顺序。
如果您使用的是 Python 3.7 或更高版本*,您可以指定字典中项目的顺序,因为插入顺序会保留。创建一个新字典并按您喜欢的顺序插入项目:
def reorder_items(d, keys):
d = d.copy() #we're going to destructively modify d, so make a copy first
result = {}
for key in keys:
if key in d:
result[key] = d.pop(key)
#the user might not have supplied all the keys belonging to d,
#so insert anything we haven't touched yet
result.update(d)
return result
d = {
'host': '192.168.0.1',
'name': 'my_new_name',
'port': 443,
'something_more': 'hello'
}
desired_key_order = ('name', 'something_more', 'host', 'port')
goal = reorder_items(d, desired_key_order)
print(goal)
结果:
{'name': 'my_new_name', 'something_more': 'hello', 'host': '192.168.0.1', 'port': 443}
(*您也可以在 CPython 3.6 中执行此操作,但这是不应依赖的实现细节)
在 3.7 之前,您无法直接控制字典中项目的排序方式。但是您可以使用 collections.OrderedDict
类型。使用前面代码块中的函数,将 result = {}
切换为 result = collections.OrderedDict()
.
更简洁(尽管有点不透明)的方法是:
result = {key:d[key] for category in (desired_key_order, d.keys()) for key in category if key in d}
#or, for versions prior to 3.7,
result = collections.OrderedDict((key, d[key]) for category in (desired_key_order, d.keys()) for key in category if key in d)
这利用了字典理解和 OrderedDict 可以用重复的键构造的事实,同时保持与每个键的第一次出现相关的顺序。
这仍然比 jpp 的解决方案长一点,因为它试图变得更容错。即使 d
包含 desired_key_order
不包含的键,它也能工作,反之亦然。未指定顺序的项目将出现在具有指定顺序的项目之后的结果中。
如果您使用的是 Python <3.7,OrderedDict
会保留项目的顺序:
from collections import OrderedDict
d = OrderedDict([
('name', 'my_new_name'),
('something_more', 'hello'),
('host', '192.168.0.1'),
('port', 443)
])
# OrderedDict([('name', 'my_new_name'), ('something_more', 'hello'), ('host', '192.168.0.1'), ('port', 443)])
您可以使用列表理解将元组列表提供给 collections.OrderedDict
:
from collections import OrderedDict
d = {'host': '192.168.0.1', 'name': 'my_new_name',
'port': 443, 'something_more': 'hello'}
key_order = ('name', 'something_more', 'host', 'port')
res = OrderedDict([(k, d[k]) for k in key_order])
OrderedDict([('name', 'my_new_name'),
('something_more', 'hello'),
('host', '192.168.0.1'),
('port', 443)])
适用于 Python 2.x 以后。对于 Python 3.7+,您可以依赖插入顺序并使用常规字典。