列表理解,创建n个唯一的字典副本。

问题描述 投票:0回答:1

我有两个字典键列表:一个是 "外 "字典键列表,一个是 "内 "字典键列表。

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 dictionary list-comprehension deep-copy
1个回答
0
投票

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 由天才卢西亚诺-拉马略所著。

© www.soinside.com 2019 - 2024. All rights reserved.