我正在尝试将一个对象列表转换为一个嵌套的dict,索引可以访问它。
以下代码适用于两级嵌套字典。我想把它扩大到任何级别的灵活工作。
from collections import namedtuple
import pprint
Holding = namedtuple('holding', ['portfolio', 'ticker', 'shares'])
lst = [
Holding('Large Cap', 'TSLA', 100),
Holding('Large Cap', 'MSFT', 200),
Holding('Small Cap', 'UTSI', 500)
]
def indexer(lst, indexes):
"""Creates a dynamic nested dictionary based on indexes."""
result = {}
for item in lst:
index0 = getattr(item, indexes[0])
index1 = getattr(item, indexes[1])
result.setdefault(index0, {}).setdefault(index1, [])
result[index0][index1].append(item)
return result
d = indexer(lst, ['portfolio', 'ticker'])
pp = pprint.PrettyPrinter()
pp.pprint(d)产出:
{'Large Cap': {'MSFT': [holding(portfolio='Large Cap', ticker='MSFT', shares=200)],
'TSLA': [holding(portfolio='Large Cap', ticker='TSLA', shares=100)]},
'Small Cap': {'UTSI': [holding(portfolio='Small Cap', ticker='UTSI', shares=500)]}}发布于 2017-12-26 23:27:05
实现嵌套字典的最好方法之一是Aaron的回答 to the implement 实现嵌套字典的最佳方法是什么?。这是一个在自生化编程语言中实现名为“Perl”的类型的示例。
无论如何,在这里使用一个是有用的,因为它意味着您只需要调用setdefault()来获取类似树的数据结构的“叶子”(这是list的,而不是子词典)。
因此,这里有一个你的问题的答案,利用它:
from collections import namedtuple
from functools import reduce
from operator import attrgetter
from pprint import pprint
Holding = namedtuple('Holding', ['portfolio', 'ticker', 'shares'])
lst = [Holding('Large Cap', 'TSLA', 100),
Holding('Large Cap', 'MSFT', 200),
Holding('Small Cap', 'UTSI', 500),]
def indexer(lst, indexes):
""" Creates a dynamic nested dictionary based on indexes. """
class Vividict(dict):
""" dict subclass which dynamically creates sub-dictionaries when
they're first referenced (and don't exist).
See https://stackoverflow.com/a/19829714/355230
"""
def __missing__(self, key):
value = self[key] = type(self)()
return value
result = Vividict()
index_getters = attrgetter(*indexes)
for item in lst:
*indices, leaf = index_getters(item) # Leaves are lists, not dicts.
target = reduce(lambda x, y: x[y], indices, result)
target.setdefault(leaf, []).append(item)
return result
d = indexer(lst, ['portfolio', 'ticker'])
pprint(d)
print()
d = indexer(lst, ['portfolio', 'ticker', 'shares'])
pprint(d)输出:
{'Large Cap': {'MSFT': [Holding(portfolio='Large Cap', ticker='MSFT', shares=200)],
'TSLA': [Holding(portfolio='Large Cap', ticker='TSLA', shares=100)]},
'Small Cap': {'UTSI': [Holding(portfolio='Small Cap', ticker='UTSI', shares=500)]}}
{'Large Cap': {'MSFT': {200: [Holding(portfolio='Large Cap', ticker='MSFT', shares=200)]},
'TSLA': {100: [Holding(portfolio='Large Cap', ticker='TSLA', shares=100)]}},
'Small Cap': {'UTSI': {500: [Holding(portfolio='Small Cap', ticker='UTSI', shares=500)]}}}https://stackoverflow.com/questions/47983728
复制相似问题