从多维列表创建字典而不复制键
Create dictionary from multi-dimensional list without duplicating keys
我想把一个包含多个元素的元组列表变成一个多维字典,而不用重复键。因此,如果以下是我的原始列表:
myList = [('jeep', 'red', 2002, 4), ('jeep', 'red', 2003, 6), ('jeep', 'blue', 2003, 4), ('bmw', 'black', 2015, 8)]
我想把上面的内容变成这种格式的字典:
{'jeep':
{'red': [
[2002, 4],
[2003, 6]]
'blue': [
[2003, 4]]
},
'bmw':
{'black': [
[2015, 8]]
}
}
我似乎在 Python 的 defaultdict 上走在了正确的道路上,但我似乎无法完全解决这个问题。谢谢!
大量使用 dict.setdefault
...
myList = [('jeep', 'red', 2002, 4), ('jeep', 'red', 2003, 6), ('jeep', 'blue', 2003, 4), ('bmw', 'black', 2015, 8)]
d = {}
for model, colour, year, month in myList:
d.setdefault(model, {}).setdefault(colour, []).append([year, month])
对于 myList
中的每个项目,获取模型的当前字典或使用新的空字典创建键,然后使用该字典检索该颜色的列表,或设置键使用新的空列表,然后将年份和月份作为 2 元素列表附加到该列表...
给你 d
:
{'bmw': {'black': [[2015, 8]]},
'jeep': {'blue': [[2003, 4]], 'red': [[2002, 4], [2003, 6]]}}
因为你想要的本质上是一个树数据结构,具有一定数量的级别和叶子列表,我会通过将细节封装在自定义字典子类中来更明确地说明这一切,因为它可以进行转换非常简单。
这是应用于您的数据的数据结构的通用版本:
class TreeContainer(dict):
def __init__(self, max_levels, leaf_factory=lambda: None, level=1):
self.max_levels = max_levels
self.level = level
self.leaf_factory = leaf_factory
def __missing__(self, key):
if self.level < self.max_levels: # need another level?
value = self[key] = type(self)(self.max_levels, self.leaf_factory,
self.level+1)
else:
value = self[key] = self.leaf_factory()
return value
myList = [("jeep", "red", 2002, 4), ("jeep", "red", 2003, 6),
("jeep", "blue", 2003, 4), ("bmw", "black", 2015, 8)]
vehicles = TreeContainer(2, list)
for model, color, year, month in myList: # convert list to dictionary
vehicles[model][color].append([year, month])
from pprint import pprint
pprint(vehicles)
输出:
{'bmw': {'black': [[2015, 8]]},
'jeep': {'blue': [[2003, 4]], 'red': [[2002, 4], [2003, 6]]}}
我想把一个包含多个元素的元组列表变成一个多维字典,而不用重复键。因此,如果以下是我的原始列表:
myList = [('jeep', 'red', 2002, 4), ('jeep', 'red', 2003, 6), ('jeep', 'blue', 2003, 4), ('bmw', 'black', 2015, 8)]
我想把上面的内容变成这种格式的字典:
{'jeep':
{'red': [
[2002, 4],
[2003, 6]]
'blue': [
[2003, 4]]
},
'bmw':
{'black': [
[2015, 8]]
}
}
我似乎在 Python 的 defaultdict 上走在了正确的道路上,但我似乎无法完全解决这个问题。谢谢!
大量使用 dict.setdefault
...
myList = [('jeep', 'red', 2002, 4), ('jeep', 'red', 2003, 6), ('jeep', 'blue', 2003, 4), ('bmw', 'black', 2015, 8)]
d = {}
for model, colour, year, month in myList:
d.setdefault(model, {}).setdefault(colour, []).append([year, month])
对于 myList
中的每个项目,获取模型的当前字典或使用新的空字典创建键,然后使用该字典检索该颜色的列表,或设置键使用新的空列表,然后将年份和月份作为 2 元素列表附加到该列表...
给你 d
:
{'bmw': {'black': [[2015, 8]]},
'jeep': {'blue': [[2003, 4]], 'red': [[2002, 4], [2003, 6]]}}
因为你想要的本质上是一个树数据结构,具有一定数量的级别和叶子列表,我会通过将细节封装在自定义字典子类中来更明确地说明这一切,因为它可以进行转换非常简单。
这是应用于您的数据的数据结构的通用版本:
class TreeContainer(dict):
def __init__(self, max_levels, leaf_factory=lambda: None, level=1):
self.max_levels = max_levels
self.level = level
self.leaf_factory = leaf_factory
def __missing__(self, key):
if self.level < self.max_levels: # need another level?
value = self[key] = type(self)(self.max_levels, self.leaf_factory,
self.level+1)
else:
value = self[key] = self.leaf_factory()
return value
myList = [("jeep", "red", 2002, 4), ("jeep", "red", 2003, 6),
("jeep", "blue", 2003, 4), ("bmw", "black", 2015, 8)]
vehicles = TreeContainer(2, list)
for model, color, year, month in myList: # convert list to dictionary
vehicles[model][color].append([year, month])
from pprint import pprint
pprint(vehicles)
输出:
{'bmw': {'black': [[2015, 8]]},
'jeep': {'blue': [[2003, 4]], 'red': [[2002, 4], [2003, 6]]}}