我在python中有一个深度嵌套的字典,占用了大量的空间。有没有办法缩写像这样的东西
master_dictionary['sub_categories'][sub_cat_name]['attributes'][attribute_name]['special_type']['nested_children'][child_cat_name][color] = blue
以此为例
nested_child_info[color] = blue
还有它编辑字典吗?我希望这是有道理的。
答案 0 :(得分:4)
nested_child_info = master_dictionary['sub_categories'][sub_cat_name]['attributes'][attribute_name]['special_type']['nested_children'][child_cat_name]
nested_child_info[color] = blue
nested_child_info
是引用,因此更改其内容将会更改master_dictionary
的内容。
答案 1 :(得分:3)
是的,你可以。
>>> dict1 = {'foo':{'bar':{'baz':0}}}
>>> dict2 = dict1['foo']['bar']
>>> dict2['baz'] = 1
>>> dict1
{'foo': {'bar': {'baz': 1}}} # dict1 has been modified
答案 2 :(得分:3)
与@fferri相似。您始终必须在 long 列表中指定项目。使用reduce
和getitem
获取引用到最终字典:
from functools import reduce
from operator import getitem
d = {1:{2:{3:{4:5}}}}
foo = 2
items = [1,foo,3]
result = d
info = reduce(getitem, items, d)
>>> info[4]
5
>>> d
{1: {2: {3: {4: 5}}}}
>>> info[4] = 99
>>> d
{1: {2: {3: {4: 99}}}}
我还在玩一个类,但它似乎没有很多优点 - 除了你可以自定义一个键错误异常,以便错误消息告诉你哪个键缺少哪个深度。
class Drilldown:
def __init__(self, d, path):
#self.final = reduce(getitem, path, d)
self.final = d
for i, item in enumerate(path, 1):
try:
self.final = self.final[item]
except KeyError as e:
msg = ''.join('[{}]' for _ in range(i))
msg = msg.format(*path[:i])
msg = 'The last key in the path "{}" does not exist'.format(msg)
e.args = [msg]
raise
def __call__(self, item):
return self.final[item]
def __setitem__(self, item, value):
self.final[item] = value
def __getitem__(self, item):
return self.final[item]
def __str__(self):
return str(self.final)
def __repr__(self):
return repr(self.final)
>>> z = 19
>>> items = [1,2,z]
>>> q = Drilldown(d,items)
Traceback (most recent call last):
File "<pyshell#68>", line 1, in <module>
q = Drilldown(d,items)
File "C:\pyProjects33\tmp.py", line 32, in __init__
self.final = self.final[item]
KeyError: 'The last key in the path "[1][2][19]" does not exist'
>>>
>>> #normal usage
>>> items = [1,2,3]
>>> q = Drilldown(d,items)
>>> d
{1: {2: {3: {4: 5}}}}
>>> q
{4: 5}
>>> q(4)
5
>>> q[4]
5
>>> q[4] += 20
>>> q
{4: 25}
>>> d
{1: {2: {3: {4: 25}}}}
>>> q['foo'] = '99'
>>> q
{4: 25, 'foo': '99'}
>>> d
{1: {2: {3: {4: 25, 'foo': '99'}}}}
>>>
答案 3 :(得分:2)
你可以这样做吗?
thing = {1: {2: {3: {4: {'hello': 'world'}}}}}
a = thing[1]
b = a[2]
c = b[3]
d = c[4]
print(d) # {'hello': 'world'}
答案 4 :(得分:2)
由于字典是可变的,实际上这恰好就像你期望的那样:
>>> test = {'outer': 'thing', 'inner': {'thing': 'im the inner thing'}}
>>> inner_thing = test['inner']
>>> inner_thing
{'thing': 'im the inner thing'}
>>> inner_thing['thing'] = 'im something new'
>>> inner_thing
{'thing': 'im something new'}
>>> test
{'outer': 'thing', 'inner': {'thing': 'im something new'}}
这是因为可变对象在python中通过引用传递,而不是作为副本传递(关于此的大量文章,所以不详细说明)。
但是,值得注意的是,您可能实际上并不想更改原始字典,因为它可能会对使用此变量的其他代码产生不良影响(这取决于您的代码库)。在这种情况下,我通常会复制我需要变异的数据以避免副作用:
>>> from copy import deepcopy
>>> test = {'outer': 'thing', 'inner': {'thing': 'im the inner thing'}}
>>> new_test = deepcopy(test)
>>> inner_thing = test['inner']
>>> inner_thing['thing'] = 'im something new'
>>> test
{'outer': 'thing', 'inner': {'thing': 'im something new'}}
>>> new_test
{'outer': 'thing', 'inner': {'thing': 'im the inner thing'}}
答案 5 :(得分:2)
如果你有一些&#34;固定&#34;键总是可以创建一个函数:
考虑这个例子:
d = dict(a=dict(sub_categories=dict(b=1)))
def changevalue(value, lvl1, lvl2):
d[lvl1]['sub_categories'][lvl2] = value
changevalue(2,'a','b')
print(d)
#{'a': {'sub_categories': {'b': 2}}}
在你的情况下,你想要解除:
[sub_cat_name],[attribute_name],[child_cat_name],[color] ...也许