我有一个文本字符串列表,需要从中构建一棵树,据我所知,实现此目标的适当数据结构是字典。 每个字符串的大小是固定的,并且所有元素的格式都相同,因此不需要其他检查。 列表的每个记录都是以DD / MM / YYYY格式表示的日期,并且年/年应该在树的根上(键,此处没有重复项),每年可能是多个月(在此范围内没有重复的月份)值),每月每个月数天(同一个月内没有重复的天数)。
字符串列表的示例:
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']
除了解决方案外,如果可以提供其他解决方案,我还想解释一下。
这是我到目前为止写的,这显然是错误的,因为结果是只有最后两项的字典。
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']}}
答案 0 :(得分:3)
有多种方法可以实现此目的。您可以使用#include
模块中的defaultdict
。但这也可以使用普通的dict.setdefault
方法来完成。
collections
如果 key 在词典中,请返回其值。如果不是,请插入 key ,其值为 default 并返回 default 。 default 默认为 None 。
我们遍历数据,将其分为日,月和年字符串。然后,我们在基树中查找年密钥,如果不存在,则为其创建一个新的空字典。然后,我们在该年份dict中查找一个月密钥,如果不存在则为其创建一个新列表。最后,我们将日期字符串附加到月份列表中。
setdefault(key[, default])
输出
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)
我们可以将主循环的3个步骤合并为一行,但是阅读起来有点困难:
{'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']}}
答案 1 :(得分:0)
您不需要树。您可以使用字典,将列表作为最里面的值。
您可以使用defaultdict
作为主要结构
result = defaultdict(defaultdict(list))
for date in data:
day, month, year = date.split('/')
result[year][month].append(day)
defaultdict
所做的是
append
。如果没有列表,则会创建一个新的空列表。month
,假设已经有一个字典作为其值。如果没有,则会创建一个新的。