Предположим, что словарь выглядит следующим образом, в котором у нас есть строка с некоторым номером ключа (не обязательно в любом порядке, и не гарантируется, что она будет в непрерывной последовательности, и единственный шаблон, которому будут следовать ключи, - это строка случайного ключа будет иметь номер в конце строки после -
):
nested_dict = {
"outter_key_layer-3": {
"inner_key_layer-4": "random_value",
"inner_key_layer-2": "random_value",
...
"inner_key_layer-11": "random_value",
"inner_key_layer-22": "random_value",
...
...
"inner_key_layer-31": "random_value",
"inner_key_layer-112": "random_value",
...
},
"outter_key_layer-54": {
"inner_key_layer-1": "random_value",
"inner_key_layer-2": "random_value",
...
"inner_key_layer-11": "random_value",
"inner_key_layer-112": "random_value",
...
"inner_key_layer-12": "random_value",
"inner_key_layer-11": "random_value",
...
},
...
"outter_key_layer-13": {
"inner_key_layer-1": "random_value",
"inner_key_layer-2": "random_value",
...
"inner_key_layer-5": "random_value",
"inner_key_layer-10": "random_value",
...
"inner_key_layer-6": "random_value",
"inner_key_layer-23": "random_value",
...
},
...
}
Как я мог добиться следующего, когда ключи расположены в алфавитном порядке, но числа также учитываются как целые числа для сортировки:
nested_dict = {
"outter_key_layer-1": {
"inner_key_layer-1": "random_value",
"inner_key_layer-2": "random_value",
...
"inner_key_layer-11": "random_value",
"inner_key_layer-12": "random_value",
...
...
"inner_key_layer-111": "random_value",
"inner_key_layer-112": "random_value",
...
},
"outter_key_layer-2": {
"inner_key_layer-1": "random_value",
"inner_key_layer-2": "random_value",
...
"inner_key_layer-11": "random_value",
"inner_key_layer-12": "random_value",
...
"inner_key_layer-111": "random_value",
"inner_key_layer-112": "random_value",
...
},
...
"outter_key_layer-11": {
"inner_key_layer-1": "random_value",
"inner_key_layer-2": "random_value",
...
"inner_key_layer-11": "random_value",
"inner_key_layer-12": "random_value",
...
"inner_key_layer-111": "random_value",
"inner_key_layer-112": "random_value",
...
},
...
}
Попытался изменить следующее из ранее заданного вопроса, но у меня ничего не получилось, например, попытка отфильтровать целые числа и как-то их отсортировать:
sorted_dict = {key: dict(sorted(nested_dict[key].items())) for key in sorted(nested_dict)}
С учетом вышеизложенного вложенные внутренние ключи не будут отсортированы должным образом, числовые значения все равно будут восприниматься как строки: inner_key_layer-1
, inner_key_layer-11
, ..., inner_key_layer-12
, inner_key_layer-2
...
Я знаю, что существует множество различных вопросов по вариантам использования, связанных с сортировкой вещей с помощью Python, но любая помощь или предложения будут приветствоваться. Спасибо.
Л.Э.: Проведя дополнительные исследования, я наткнулся на пакет natsort
, и его использование таким образом в основном дает то, что я ищу:
from natsort import natsorted
my_sorted_dict = {key: dict(natsorted(nested_dict[key].items())) for key in sorted(nested_dict)}
Однако мне все еще интересно, есть ли способ сделать это без использования или установки другого пакета.
Хитрость заключается в том, чтобы разделить ключи, чтобы получить список элементов для сортировки. Не забудьте преобразовать последнее случайное число в int()
. Элементы в списке сравниваются поэлементно.
Здесь я использовал рекурсивный подход, но поскольку он вложен только на один уровень, вы можете заменить его другим циклом for:
from pprint import pprint
nested_dict = {
"outter_key_layer-3": {
"inner_key_layer-4": "random_value",
"inner_key_layer-2": "random_value",
"inner_key_layer-11": "random_value",
"inner_key_layer-22": "random_value",
"inner_key_layer-31": "random_value",
"inner_key_layer-112": "random_value",
},
"outter_key_layer-54": {
"inner_key_layer-1": "random_value",
"inner_key_layer-2": "random_value",
"inner_key_layer-11": "random_value",
"inner_key_layer-112": "random_value",
"inner_key_layer-12": "random_value",
},
"outter_key_layer-13": {
"inner_key_layer-1": "random_value",
"inner_key_layer-2": "random_value",
"inner_key_layer-5": "random_value",
"inner_key_layer-10": "random_value",
"inner_key_layer-6": "random_value",
"inner_key_layer-23": "random_value",
},
}
def sort_key_func(x: tuple):
key, _value = x
splitted = key.split("-")
splitted[-1] = int(splitted[-1])
return splitted
def sorted_dict(d: dict):
result = dict(sorted(d.items(), key=sort_key_func))
for k, v in result.items():
if isinstance(v, dict):
result[k] = sorted_dict(v)
return result
pprint(sorted_dict(nested_dict), sort_dicts=False)
выход:
{'outter_key_layer-3': {'inner_key_layer-2': 'random_value',
'inner_key_layer-4': 'random_value',
'inner_key_layer-11': 'random_value',
'inner_key_layer-22': 'random_value',
'inner_key_layer-31': 'random_value',
'inner_key_layer-112': 'random_value'},
'outter_key_layer-13': {'inner_key_layer-1': 'random_value',
'inner_key_layer-2': 'random_value',
'inner_key_layer-5': 'random_value',
'inner_key_layer-6': 'random_value',
'inner_key_layer-10': 'random_value',
'inner_key_layer-23': 'random_value'},
'outter_key_layer-54': {'inner_key_layer-1': 'random_value',
'inner_key_layer-2': 'random_value',
'inner_key_layer-11': 'random_value',
'inner_key_layer-12': 'random_value',
'inner_key_layer-112': 'random_value'}}