循环嵌套dict只返回最后一个值,除非我将其分配给另一个di

2024-07-02 10:36:50 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个结构如下的dict products

{'Cheese': {'Cheese': {'comment': 'Markets quiet this week', 'indicator': 'Flat', 'pricelow': '3385', 'priceaverage': '3385', 'pricehigh': '3385'}}, 'MPC': {'MPC70': {'comment': 'Large buyers', 'indicator': 'Flat', 'pricelow': '8598', 'priceaverage': '8929', 'pricehigh': '9039'}, 'MPI:': {'comment': 'Large buyers', 'indicator': 'Flat', 'pricelow': '8598', 'priceaverage': '8929', 'pricehigh': '9039'}, 'MPC85': {'comment': 'Large buyers', 'indicator': 'Flat', 'pricelow': '8598', 'priceaverage': '8929', 'pricehigh': '9039'}}}

我想解析嵌套结构,为此我想取产品名“Cheese”、“MPC70”、“MPI”、“MPC85”,将其作为“name”添加到内部dict中,并将其全部放入一个列表中。(分类(“奶酪”和“MPC”不再重要,并且将丢失)拥有这样的东西:

^{pr2}$

到目前为止还不错,但当我在字典中查找“MPC”类别中的所有产品时,名称是“MPC85” 我的循环是这样的:

for item in products:
  for subitem in products[item]:
    products[item][subitem]['name'] = subitem
    productlist.append(products[item][subitem])
    #print products[item][subitem]
    #print products[item][subitem]['name']
    #print  item + ' ' + subitem
print productlist

对于任何带注释的print语句,输出完全是我想要的,但是如果我打印整个列表,“MPC”产品的“name”键是“MPC85”\

经过一些尝试和错误,并确认@spectras循环实际起作用,我想如果我将dict赋给另一个变量

products2 = products

将循环改为循环products2,而不是products,整个过程正常。在

所以问题是:为什么python似乎在循环一个dict时有问题,而当我将dict赋给另一个变量时,它却如预期的那样做了?

编辑: 我做了什么,得到了什么:

In [3]: print products
{'Cheese': {'Cheese': {'comment': 'Markets quiet this week', 'indicator': 'Flat', 'pricelow': '3385', 'priceaverage': '3385', 'pricehigh': '3385'}}, 'MPC': {'MPC70': {'comment': 'Large buyers.High Ground.', 'indicator': 'Flat', 'pricelow': '8598', 'priceaverage': '8929', 'pricehigh': '9039'}, 'MPI:': {'comment': 'Large buyers.High Ground.', 'indicator': 'Flat', 'pricelow': '8598', 'priceaverage': '8929', 'pricehigh': '9039'}, 'MPC85': {'comment': 'Large buyers.High Ground.', 'indicator': 'Flat', 'pricelow': '8598', 'priceaverage': '8929', 'pricehigh': '9039'}}, 'Whey Powder': {'Whey Powder': {'comment': 'Dry Whey futures drop', 'indicator': 'Down', 'pricelow': '1124', 'priceaverage': '1124', 'pricehigh': '1124'}}, 'Casein': {'Casein': {'comment': 'No changes.', 'indicator': 'Down', 'pricelow': '7165', 'priceaverage': '7605', 'pricehigh': '8157'}}, 'Lactose': {'Lactose': {'comment': 'Lactose prices remain unchanged', 'indicator': 'Down', 'pricelow': '683', 'priceaverage': '683', 'pricehigh': '683'}}, 'Powders': {'NFDM': {'comment': 'Export volumes dropped.', 'indicator': 'Up', 'pricelow': '2408', 'priceaverage': '2408', 'pricehigh': '2408'}}, 'Caseinate': {'Caseinate': {'comment': 'actively selling.requested pricing.', 'indicator': 'Down', 'pricelow': '7716', 'priceaverage': '8598', 'pricehigh': '9479'}}, 'Cream': {'Butter': {'comment': 'Butter stocks increased', 'indicator': 'Down', 'pricelow': '3847', 'priceaverage': '3847', 'pricehigh': '3847'}}, 'WPC': {'WPC80': {'comment': 'WPC 80 \xe2\x80\x93 Supply continues.', 'indicator': 'Down', 'pricelow': '5300', 'priceaverage': '7165', 'pricehigh': '8267'}, 'IWPC80': {'comment': 'WPC 80 \xe2\x80\x93 Supply continues.', 'indicator': 'Down', 'pricelow': '5300', 'priceaverage': '7165', 'pricehigh': '8267'}}}

In [4]: %paste
        for item in products:
                for subitem in products[item]:
                        products[item][subitem]['name'] = subitem
                        #print products[item][subitem]
                        #print products[item][subitem]['name']
                        productlist.append(products[item][subitem])
                        #print  item + ' ' + subitem
                        #print products[item][subitem]['name']
                        #print products[item]
                        #print products[item][subitem]
        print productlist

## -- End pasted text --
[{'comment': 'Markets quiet this week', 'indicator': 'Flat', 'name': 'Cheese', 'pricelow': '3385', 'priceaverage': '3385', 'pricehigh': '3385'}, {'comment': 'Large buyers.High Ground.', 'indicator': 'Flat', 'name': 'MPC85', 'pricelow': '8598', 'priceaverage': '8929', 'pricehigh': '9039'}, {'comment': 'Large buyers.High Ground.', 'indicator': 'Flat', 'name': 'MPC85', 'pricelow': '8598', 'priceaverage': '8929', 'pricehigh': '9039'}, {'comment': 'Large buyers.High Ground.', 'indicator': 'Flat', 'name': 'MPC85', 'pricelow': '8598', 'priceaverage': '8929', 'pricehigh': '9039'}, {'comment': 'Dry Whey futures drop', 'indicator': 'Down', 'name': 'Whey Powder', 'pricelow': '1124', 'priceaverage': '1124', 'pricehigh': '1124'}, {'comment': 'No changes.', 'indicator': 'Down', 'name': 'Casein', 'pricelow': '7165', 'priceaverage': '7605', 'pricehigh': '8157'}, {'comment': 'Lactose prices remain unchanged', 'indicator': 'Down', 'name': 'Lactose', 'pricelow': '683', 'priceaverage': '683', 'pricehigh': '683'}, {'comment': 'Export volumes dropped.', 'indicator': 'Up', 'name': 'NFDM', 'pricelow': '2408', 'priceaverage': '2408', 'pricehigh': '2408'}, {'comment': 'actively selling.requested pricing.', 'indicator': 'Down', 'name': 'Caseinate', 'pricelow': '7716', 'priceaverage': '8598', 'pricehigh': '9479'}, {'comment': 'Butter stocks increased', 'indicator': 'Down', 'name': 'Butter', 'pricelow': '3847', 'priceaverage': '3847', 'pricehigh': '3847'}, {'comment': 'WPC 80 \xe2\x80\x93 Supply continues.', 'indicator': 'Down', 'name': 'IWPC80', 'pricelow': '5300', 'priceaverage': '7165', 'pricehigh': '8267'}, {'comment': 'WPC 80 \xe2\x80\x93 Supply continues.', 'indicator': 'Down', 'name': 'IWPC80', 'pricelow': '5300', 'priceaverage': '7165', 'pricehigh': '8267'}]

In [5]: type(products)
Out[5]: dict

In [6]: type(products['Cheese']
   ...: )
Out[6]: dict

编辑2: Ran建议从评论中截取,输出:

    In [3]: print products
{'Cheese': {'Cheese': {'comment': 'Markets quiet this week', 'indicator': 'Flat', 'pricelow': '3385', 'priceaverage': '3385', 'pricehigh': '3385'}}, 'MPC': {'MPC70': {'comment': 'Large buyers.High Ground.', 'indicator': 'Flat', 'pricelow': '8598', 'priceaverage': '8929', 'pricehigh': '9039'}, 'MPI:': {'comment': 'Large buyers.High Ground.', 'indicator': 'Flat', 'pricelow': '8598', 'priceaverage': '8929', 'pricehigh': '9039'}, 'MPC85': {'comment': 'Large buyers.High Ground.', 'indicator': 'Flat', 'pricelow': '8598', 'priceaverage': '8929', 'pricehigh': '9039'}}, 'Whey Powder': {'Whey Powder': {'comment': 'Dry Whey futures drop', 'indicator': 'Down', 'pricelow': '1124', 'priceaverage': '1124', 'pricehigh': '1124'}}, 'Casein': {'Casein': {'comment': 'No changes.', 'indicator': 'Down', 'pricelow': '7165', 'priceaverage': '7605', 'pricehigh': '8157'}}, 'Lactose': {'Lactose': {'comment': 'Lactose prices remain unchanged', 'indicator': 'Down', 'pricelow': '683', 'priceaverage': '683', 'pricehigh': '683'}}, 'Powders': {'NFDM': {'comment': 'Export volumes dropped.', 'indicator': 'Up', 'pricelow': '2408', 'priceaverage': '2408', 'pricehigh': '2408'}}, 'Caseinate': {'Caseinate': {'comment': 'actively selling.requested pricing.', 'indicator': 'Down', 'pricelow': '7716', 'priceaverage': '8598', 'pricehigh': '9479'}}, 'Cream': {'Butter': {'comment': 'Butter stocks increased', 'indicator': 'Down', 'pricelow': '3847', 'priceaverage': '3847', 'pricehigh': '3847'}}, 'WPC': {'WPC80': {'comment': 'WPC 80 \xe2\x80\x93 Supply continues.', 'indicator': 'Down', 'pricelow': '5300', 'priceaverage': '7165', 'pricehigh': '8267'}, 'IWPC80': {'comment': 'WPC 80 \xe2\x80\x93 Supply continues.', 'indicator': 'Down', 'pricelow': '5300', 'priceaverage': '7165', 'pricehigh': '8267'}}}

In [4]: %paste
from pprint import pprint; from itertools import chain; pprint([(key, type(val).__name__, id(val)) for key, val in chain.from_iterable(x.items() for x in products.values())])

## -- End pasted text --
[('Cheese', 'dict', 64885352L),
 ('MPC70', 'dict', 64887800L),
 ('MPI:', 'dict', 64887800L),
 ('MPC85', 'dict', 64887800L),
 ('Whey Powder', 'dict', 65061480L),
 ('Casein', 'dict', 65061752L),
 ('Lactose', 'dict', 65062024L),
 ('NFDM', 'dict', 65062296L),
 ('Caseinate', 'dict', 65062568L),
 ('Butter', 'dict', 65063112L),
 ('WPC80', 'dict', 65062840L),
 ('IWPC80', 'dict', 65062840L)]

Tags: namecommentitemdictindicatorproductsdownlarge
1条回答
网友
1楼 · 发布于 2024-07-02 10:36:50

好吧,问题现在清楚了。在

关于我给你复制粘贴的样本线的说明:

from pprint import pprint
from itertools import chain
pprint([(key, type(val).__name__, id(val))
        for key, val in chain.from_iterable(x.items() for x in products.values())])

这将遍历每个二级词典并打印:

  1. 用来访问它的键。在
  2. 字典的类型(以确保它实际上是dict)
  3. 字典的唯一标识符。在

因此,考虑到这些结果,有一点需要注意:

^{pr2}$

→您的某些产品共享同一个dict。请参阅MPC70、MPI和MPC85如何具有相同的唯一标识符?在

结果,不是添加三个不同的dict,每个dict都添加了name到产品列表中,而是最终添加了三次相同的dict,每次循环迭代都覆盖{}。在

这也解释了为什么复制粘贴改变了这个问题。当复制粘贴时,您创建了三个不同的dict,它们看起来正好相同。在

我们现在可以修复您的代码,因为我们知道必须显式地复制产品,而不是简单地重复使用它们:

for item in products:
  for subitem in products[item]:
    product = products[item][subitem].copy()
    product['name'] = subitem
    productlist.append(product)

另外,同样的循环写得更有效率:

for item in products.values():
  for subkey, subitem in item.items():
    product = subitem.copy()
    product['name'] = subkey
    productlist.append(product)

相关问题 更多 >