Если вы используете 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)
При этом используется тот факт, что DICT-понимания и OrderedDict могут быть созданы с дубликатами ключей, оставаясь в порядке по отношению к первому появлению каждого ключа.
Это все еще немного дольше, чем решение jpp, так как оно пытается быть немного более устойчивым к ошибкам. Это работает, даже если d
содержит ключи, которых нет desired_key_order
, и наоборот. Элементы, порядок которых не указан, появятся в результате после элементов, для которых указан порядок.