从每个键具有多个唯一值的字符串列表创建一个 3 级字典
Create a 3 level dictionary from a list of strings with multiple uniqe values for each key
我有一个文本字符串列表,我需要从中构建一棵树,据我所知,实现这一点的正确数据结构是一个字典。
每个字符串的大小都是固定的,所有元素的格式都是相同的,因此不需要额外的检查。
列表的每条记录都是格式为 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']
除了解决方案,如果有的话我还想解释一下以便理解。
这是我到目前为止所写的内容,但显然是错误的,因为结果是一本只有最后 2 项的字典。
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']}}
你不需要一棵树。您可以使用字典的字典,将列表作为最内层的值。
您可以使用 defaultdict
作为您的主要结构
result = defaultdict(defaultdict(list))
for date in data:
day, month, year = date.split('/')
result[year][month].append(day)
defaultdict
所做的是
- 对于内部字典:你可以直接
append
。如果没有列表,则创建一个新的空列表。
- for the outer dict: 同样,你可以参考键
month
假设已经有一个dict作为它的值。如果没有,则创建一个新的。
有多种方法可以实现这一点。您可以使用defaultdict
from the collections
module. But it can also be done use the plain dict.setdefault
方法。
setdefault(key[, default])
If key is in the dictionary, return its value. If not, insert key with a value of default and return default. default defaults to None.
我们遍历数据,将其拆分为日、月和年字符串。然后我们在基础树中寻找年份键,如果它不存在我们为它创建一个新的空字典。然后我们在那个年份的字典中查找一个月份键,如果它不存在则为其创建一个新列表。最后,我们将日期字符串附加到月份列表。
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)
我有一个文本字符串列表,我需要从中构建一棵树,据我所知,实现这一点的正确数据结构是一个字典。 每个字符串的大小都是固定的,所有元素的格式都是相同的,因此不需要额外的检查。 列表的每条记录都是格式为 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']
除了解决方案,如果有的话我还想解释一下以便理解。
这是我到目前为止所写的内容,但显然是错误的,因为结果是一本只有最后 2 项的字典。
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']}}
你不需要一棵树。您可以使用字典的字典,将列表作为最内层的值。
您可以使用 defaultdict
作为您的主要结构
result = defaultdict(defaultdict(list))
for date in data:
day, month, year = date.split('/')
result[year][month].append(day)
defaultdict
所做的是
- 对于内部字典:你可以直接
append
。如果没有列表,则创建一个新的空列表。 - for the outer dict: 同样,你可以参考键
month
假设已经有一个dict作为它的值。如果没有,则创建一个新的。
有多种方法可以实现这一点。您可以使用defaultdict
from the collections
module. But it can also be done use the plain dict.setdefault
方法。
setdefault(key[, default])
If key is in the dictionary, return its value. If not, insert key with a value of default and return default. default defaults to None.
我们遍历数据,将其拆分为日、月和年字符串。然后我们在基础树中寻找年份键,如果它不存在我们为它创建一个新的空字典。然后我们在那个年份的字典中查找一个月份键,如果它不存在则为其创建一个新列表。最后,我们将日期字符串附加到月份列表。
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)