Python 从每个键具有多个uniqe值的字符串列表创建一个3级字典
我有一个文本字符串列表,我需要从中构建一个树,据我所知,实现这一点的正确数据结构是一个字典。 每个字符串的大小是固定的,所有元素的格式都是相同的,因此不需要进行额外的检查。 列表的每个记录都是DD/MM/YYYY格式的日期,年/年应位于树的根上(键,此处无重复项),每年的值可以是多个月(同年内无重复月),每个月的值可以是多天(同月内无重复天) 字符串列表的一个示例: 数据=['2018年2月4日'、'2018年2月5日'、'2018年2月6日'、'2018年3月1日', '10/03/2018', '08/09/2017', '09/09/2017', '11/10/2017', “2017年11月12日”、“2018年6月14日”、“2018年6月15日”、“2018年7月24日”、“2018年7月26日”、“2018年8月30日”、“2018年8月31日”、“2018年9月1日”] 除了一个解决方案,如果有任何可以提供我也想解释,以便理解 这是我到目前为止写的,显然是错误的,因为结果是一本只有最后两项的字典Python 从每个键具有多个uniqe值的字符串列表创建一个3级字典,python,python-3.x,dictionary,ordereddictionary,Python,Python 3.x,Dictionary,Ordereddictionary,我有一个文本字符串列表,我需要从中构建一个树,据我所知,实现这一点的正确数据结构是一个字典。 每个字符串的大小是固定的,所有元素的格式都是相同的,因此不需要进行额外的检查。 列表的每个记录都是DD/MM/YYYY格式的日期,年/年应位于树的根上(键,此处无重复项),每年的值可以是多个月(同年内无重复月),每个月的值可以是多天(同月内无重复天) 字符串列表的一个示例: 数据=['2018年2月4日'、'2018年2月5日'、'2018年2月6日'、'2018年3月1日', '10/03/2018'
d = {}
for item in data:
rec = item.split('/')
d.update({rec[2]:{rec[1]:(rec[0])}})
该数据的所需输出如下所示:
{'2017': {'09': ['08', '09'], '10': ['11'], '12': ['11']},
'2018': {'02': ['04', '05', '06'],
'03': ['01', '10'],
'06': ['14', '15'],
'07': ['24', '26'],
'08': ['30', '31'],
'09': ['01']}}
你不需要一棵树。您可以使用dict的dict,将列表作为最里面的值 您可以使用
defaultdict
作为主结构
result = defaultdict(defaultdict(list))
for date in data:
day, month, year = date.split('/')
result[year][month].append(day)
默认dict的作用是
- 对于内部命令:您可以直接
追加
。如果没有列表,将创建一个新的空列表
- 对于外部dict:类似地,您可以引用键
,假设已经有一个dict作为其值。如果没有,则创建一个新的month
集合
模块中的。但也可以使用简单的方法来完成
设置默认值(键[,默认值])
如果键在字典中,则返回其值。如果不是,则插入值为default的键并返回default。默认值为“无”
我们对数据进行循环,将其分为日、月和年字符串。然后我们在基础树中查找年份键,如果它不存在,我们将为它创建一个新的空dict。然后,我们在当年的dict中查找一个月键,如果它不存在,则为它创建一个新列表。最后,我们将日期字符串附加到月份列表中
from pprint import pprint
data = [
'04/02/2018', '05/02/2018', '06/02/2018', '01/03/2018', '10/03/2018', '08/09/2017', '09/09/2017',
'11/10/2017', '11/12/2017', '14/06/2018', '15/06/2018', '24/07/2018', '26/07/2018', '30/08/2018',
'31/08/2018', '01/09/2018'
]
tree = {}
for s in data:
day, mon, year = s.split('/')
ydict = tree.setdefault(year, {})
mlist = ydict.setdefault(mon, [])
mlist.append(day)
pprint(tree)
输出
{'2017': {'09': ['08', '09'], '10': ['11'], '12': ['11']},
'2018': {'02': ['04', '05', '06'],
'03': ['01', '10'],
'06': ['14', '15'],
'07': ['24', '26'],
'08': ['30', '31'],
'09': ['01']}}
我们可以将主循环的3个步骤组合成一行,但阅读起来有点困难:
for s in data:
day, mon, year = s.split('/')
tree.setdefault(year, {}).setdefault(mon, []).append(day)
请添加您的代码,您面临的问题是什么?到目前为止,我没有任何可用的代码,但我可以发布我可耻的尝试。很好,这就是最好的方式。是的,这就是最终结果应该是什么样子,抱歉,我忘了发布它。“我需要构建一个树,我知道实现这一点的正确数据结构是一个字典。”不一定。树通常使用您自己的自定义数据结构(也可能由
dict
对象组成,但可能涉及其他对象)来实现。值应为“天”@blue\u注意:您运行了这个吗?因为我很确定不能在for中拆分列表对象statement@vash_the_stampede:当然错了。谢谢,edited。没问题,我在运行嵌套的defaultdict时也遇到了一个错误,它不允许内部defaultdict是可编辑的,也许我遗漏了一些有用的、易于阅读和理解的东西。我知道python一行程序是首选,但对于我的python水平来说,更长的方式是完美的。谢谢。我想让你看看这个,我正在解决它。我正在考虑使用.split(“:”)并设置一个dict,每个键的唯一性在:
之前,然后从那里开始,检查它。我想你最好先检查一下值“day”是否在mlist中,然后再附加实际给出最终想要的结果。如果天不在mlist:mlist.append(day)@一点一点啊。我不知道你需要排除重复的天数。我以为你在说数据中永远不会有重复的日子。您的解决方案很好,但另一种选择是将日期存储在集合中而不是列表中,这将自动消除重复项,就像dict键消除重复的年份和月份一样。为此,您需要使用set.add
方法,该方法相当于list.append
。OTOH,集合是无序集合,可能不适合您的用例。@PM2Ring实际排序是用于最终目的的首选。还有一个关于pprint的问题,为什么只有一个dict是以树形打印的,而其他dict不是?我在一些较大的实际数据列表上尝试了该代码,我看到只有一个“分支”以树的形式展开,其余的则不是。