如何解决有没有办法从外面对字典进行排序
我正在尝试创建一个事件管理器,其中词典将这样存储事件
my_dict = {'2020':
{'9': {'8': ['School ']},'11': {'13': ['Doctors ']},'8': {'31': ['Interview']}
},'2021': {}}
其中外键是年份,中键是月,而最内键是日期,它导致事件列表。 我正在尝试先对其进行排序,以便按月排序,然后再次对其进行排序,以便使日排序。预先感谢
解决方法
用例
- DevOrangeCrush希望对嵌套字典在多层嵌套的键上进行排序
解决方案
-
对数据进行规范化,以便日期与ISO8601格式匹配,以便于排序
- 用简单的英语来说,这意味着请确保您始终使用两位数字表示月份和日期,并始终使用四位数表示年份
-
将原始字典数据结构重新规范化为单个字典列表,其中每个字典代表一行,并且该列表代表一个外部包含表
-
数据重组后,您正在解决一个更为知名,记录良好且更为明显的问题,如何对简单的字典列表进行排序(已在
See also
中进行了记录此答案的一部分)。
示例
import pprint
## original data is formatted as a nested dictionary,which is clumsy
my_dict = {'2020':
{'9': {'8': ['School ']},'11':
{'13': ['Doctors ']},'8':
{'31': ['Interview']}},'2021': {}
}
## we want the data formatted as a standard table (aka list of dictionary)
## this is the most common format for this kind of data as you would see in
## databases and spreadsheets
mydata_table = []
ddtemp = dict()
for year in my_dict:
for month in my_dict[year].keys():
ddtemp['month'] = '{0:02d}'.format(*[int(month)])
ddtemp['year'] = year
for day in my_dict[year][month].keys():
ddtemp['day'] = '{0:02d}'.format(*[int(day)])
mydata_row = dict()
mydata_row['year'] = '{year}'.format(**ddtemp)
mydata_row['month'] = '{month}'.format(**ddtemp)
mydata_row['day'] = '{day}'.format(**ddtemp)
mydata_row['task_list'] = my_dict[year][month][day]
mydata_row['date'] = '{year}-{month}-{day}'.format(**ddtemp)
mydata_table.append(mydata_row)
pass
pass
pass
## output result is now easily sorted and there is no data loss
## you will have to modify this if you want to deal with years that
## do not have any associated task_list data
pprint.pprint(mydata_table)
'''
## now we have something that can be sorted using well-known python idioms
## and easily manipulated using data-table semantics
## (search,sort,filter-by,group-by,select,project ... etc)
[
{'date': '2020-09-08','day': '08','month': '09','task_list': ['School '],'year': '2020'},{'date': '2020-11-13','day': '13','month': '11','task_list': ['Doctors '],{'date': '2020-08-31','day': '31','month': '08','task_list': ['Interview'],]
'''
另请参见
- How to sort a python list-of-dictionary
- How to sort objects by multiple keys
- Why you should use ISO8601 date format
- ISO8601 vs timestamp
要获取已排序的事件数据,您可以执行以下操作:
def sort_events(my_dict):
new_events_data = dict()
for year,month_data in my_dict.items():
new_month_data = dict()
for month,day_data in month_data.items():
sorted_day_data = sorted(day_data.items(),key=lambda kv: int(kv[0]))
new_month_data[month] = OrderedDict(sorted_day_data)
sorted_months_data = sorted(new_month_data.items(),key=lambda kv: int(kv[0]))
new_events_data[year] = OrderedDict(sorted_months_data)
return new_events_data
输出:
{'2020': OrderedDict([('8',OrderedDict([('31',['Interview'])])),('9',OrderedDict([('8',['School '])])),('11',OrderedDict([('13',['Doctors '])]))]),'2021': OrderedDict()}
,
无法订购简单的dict
,您可以使用OrderedDict
进行排序,但是如果只需要在迭代时对其进行排序,就可以这样做
for year in sorted(map(int,my_dict)):
year_dict = my_dict[str(year)]
for month in sorted(map(int,year_dict)):
month_dict = year_dict[str(month)]
for day in sorted(map(int,month_dict)):
events = month_dict[str(day)]
for event in events:
print(year,month,day,event)
Online Demo
转换为int
是为了确保数字之间的顺序正确,而您不会得到1,10,11,..,2,20,21
Python中的字典没有顺序,您可能想尝试可记住插入顺序的collections模块中的OrderedDict类。
当然,每当您插入一个应放置在任何现有元素之前的新元素时,您都必须对元素进行排序和重新插入。
如果您关心订单,也许其他数据结构会更好。例如列表列表。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。