我有两个字典键列表:一个是 "外 "字典键列表,一个是 "内 "字典键列表。
outer_keys = ['out1', 'out2', 'out3', 'out4' ]
inner_keys = ['in1', 'in2', 'in3' ]
我想用列表理解法来编程生成类似于以下结构的嵌套字典。
{'out1': {'in1': Decimal('0.00'), 'in2': Decimal('0.00'), 'in3': Decimal('0.00')},
'out2': {'in1': Decimal('0.00'), 'in2': Decimal('0.00'), 'in3': Decimal('0.00')},
'out3': {'in1': Decimal('0.00'), 'in2': Decimal('0.00'), 'in3': Decimal('0.00')},
'out4': {'in1': Decimal('0.00'), 'in2': Decimal('0.00'), 'in3': Decimal('0.00')}
}
我的第一次尝试如下:
from decimal import Decimal
outer_keys = ['out1', 'out2', 'out3', 'out4' ]
inner_keys = ['in1', 'in2', 'in3' ]
z = dict(zip(outer_keys, [dict(zip(inner_keys, [Decimal('0.00') for _ in inner_keys])) for _ in outer_keys]))
这样做是正确的,因为被 "外 "键引用的 "内部 "字典都是唯一的。
>>> z['out1']['in1'] is z['out2']['in1']
False
然而,对z的分配是相当困难的。 所以我试着把它分成两个赋值来简化。
x = dict(zip(inner_keys, [Decimal('0.00') for _ in inner_keys]))
y = dict(zip(outer_keys, [x for _ in outer_keys]))
这样做已经行不通了,因为 "外键 "的值 "out1",... ,"out4 "都引用了同一个字典。
>>> y['out1']['in1'] is y['out2']['in1']
True
因此,分配到一个内部字典中的项目会改变所有字典中的对应值。
>>> y['out1']['in1']
Decimal('0.00')
>>> y['out2']['in1']
Decimal('0.00')
>>> y['out1']['in1']=Decimal('1.00')
>>> y['out2']['in1']
Decimal('1.00')
>>>
我试过用我能想到的所有方法来代替... x
列表中的理解力的作业,以 y
(包括,如。copy.deepcopy(x)
和像列表片一样的 [x][:][0]
但无论我怎么做,我都无法让 python 为每个外键值创建一个由 x 引用的字典的唯一副本。 当然,除了回到原始的冗长且不可读的z赋值。
我也不明白为什么 [Decimal('0.00') for _ in inner_keys]
生成三个唯一的十进制对象,但 [x for _ in outer_keys]
生成四个对一个dict的引用。 以及如何写一个列表理解,它将生成 n 独一无二 x
.
编辑1: 看来我在检查我所尝试的一些事情是否真的有效时不够仔细。 正如@MichaelButscher在下面的评论中正确指出的,使用 x.copy()
而非 x
的任务中 y
将解决我的问题,因为它似乎做了。copy.deepcopy(x)
即使我没有意识到它的工作。
所以这当然是我可以解决的一个方法。
我也很喜欢@Ahmed I. Elsayed在下面发的dict comprehension解决方案。
这两个都比我原来复杂的作业要干净得多。z
Python 提供了 dict 理解 (也提供了 set comps!)
# IDLE ( I reformatted )
my_dict = { key: inner_keys for key in outer_keys }
my_dict
{
'out1': ['in1', 'in2', 'in3'],
'out2': ['in1', 'in2', 'in3'],
'out3': ['in1', 'in2', 'in3'],
'out4': ['in1', 'in2', 'in3']
}
如果你想把一些东西应用到第二个列表中,就像你已经使用的那样 Decimal
, 多种方式
my_dict = { key: [i.upper() for i in inner_keys ] for key in outer_keys }
my_dict
{
'out1': ['IN1', 'IN2', 'IN3'],
'out2': ['IN1', 'IN2', 'IN3'],
'out3': ['IN1', 'IN2', 'IN3'],
'out4': ['IN1', 'IN2', 'IN3']
}
或
my_dict = { key: map(str.upper, inner_keys) for key in outer_keys }
# same output as above, trimmed for readability
根据需要定制,或者在这里留言询问。
我想归功于我学习的地方。录音笔我第一次看到他们是在一本很棒的书里。流利的Python 由天才卢西亚诺-拉马略所著。