Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在嵌套dict中循环只返回最后一个值,除非我将其分配给另一个dict_Python_Python 2.7_Loops_Dictionary - Fatal编程技术网

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

Python 在嵌套dict中循环只返回最后一个值,除非我将其分配给另一个dict,python,python-2.7,loops,dictionary,Python,Python 2.7,Loops,Dictionary,我有一个dict产品,结构如下: {'Cheese': {'Cheese': {'comment': 'Markets quiet this week', 'indicator': 'Flat', 'pricelow': '3385', 'priceaverage': '3385', 'pricehigh': '3385'}}, 'MPC': {'MPC70': {'comment': 'Large buyers', 'indicator': 'Flat', 'pricelow': '8598'

我有一个dict
产品
,结构如下:

{'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”不再重要,将丢失)具有以下内容:

[{'indicator': 'Flat', 
 'comment': 'Markets quiet this week', 
 'name': 'Cheese', 
 'pricelow': '3385', 
 'priceaverage': '3385', 
 'pricehigh': '3385'}, 
{'indicator': 'Flat', 
 'comment': 'Large buyers.High Ground.', 
 'name': 'MPC70', 
 'pricelow': '4189', 
 'priceaverage': '4409', 
 'pricehigh': '5070'}, 
{'indicator': 'Flat', 
 'comment': 'Large buyers.High Ground.', 
 'name': 'MPI:', 
 'pricelow': '8598', 
 'priceaverage': '8929', 
 'pricehigh': '9039'}, 
{'indicator': 'Flat', 
 'comment': 'Large buyers.High Ground.', 
 'name': 'MPC85', 
 'pricelow': '8377', 
 'priceaverage': '8488', 
 'pricehigh': '8818'}
]
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
到目前为止还不错,但当我循环浏览“MPC”类别中所有产品的字典时,名称是“MPC85” 我的循环如下所示:

[{'indicator': 'Flat', 
 'comment': 'Markets quiet this week', 
 'name': 'Cheese', 
 'pricelow': '3385', 
 'priceaverage': '3385', 
 'pricehigh': '3385'}, 
{'indicator': 'Flat', 
 'comment': 'Large buyers.High Ground.', 
 'name': 'MPC70', 
 'pricelow': '4189', 
 'priceaverage': '4409', 
 'pricehigh': '5070'}, 
{'indicator': 'Flat', 
 'comment': 'Large buyers.High Ground.', 
 'name': 'MPI:', 
 'pricelow': '8598', 
 'priceaverage': '8929', 
 'pricehigh': '9039'}, 
{'indicator': 'Flat', 
 'comment': 'Large buyers.High Ground.', 
 'name': 'MPC85', 
 'pricelow': '8377', 
 'priceaverage': '8488', 
 'pricehigh': '8818'}
]
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
对于任何已注释的打印语句,输出都完全符合我的要求,但是如果我打印整个列表,则每个“MPC”产品的“名称”键都是“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: 从评论中删除建议,输出:

    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)]

好了,问题现在清楚了

关于我让您复制粘贴的样本行的说明:

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())])
这将通过每个2级字典并打印:

  • 用于访问它的密钥
  • 字典的类型(以确保它实际上是一个dict)
  • 字典的唯一标识符
  • 因此,考虑到这些结果,有一些重要的事情需要注意:

       [('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)]
    
    → 您的一些产品共享相同的dict。请参阅MPC70、MPI和MPC85如何具有相同的唯一标识符

    因此,不是添加三个不同的dict,每个dict都有其添加的
    名称
    ,而是添加三次相同的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)
    

    您发布的代码实际上是有效的。您可能没有发布您所拥有的内容。我只是再试一次,检查我的dict是否与我在此处显示和使用的代码相同,问题仍然存在。@Alexander。请再次检查。您问题中的示例不是有效的dict-但如果它已修复,循环将按预期工作。复制并粘贴您的真实副本de,不是你认为的那样。你在python文件中发布的代码:在python2和python3上都运行得很好。我添加了真正的字典。@spectras我可以确认你的代码可以工作,但是我的dict不工作。所以我看起来好像有一个错误。太好了,这更优雅地解决了问题。有没有办法解决这个问题从源头上解决它,即以不同的方式创建dict,这样我就不会再次遇到相同的问题了?我使用嵌套for循环和
    products[product][productname]={}
    以及赋值
    products[product][productname]['indicator']=indicator
    在最里面的循环井中,这需要整个循环代码才能确定。可能您在外循环中创建dict,然后在内循环中分配它,因此您最终为每个子项分配相同的字典。请记住,在python中,当您执行
    x=y
    时,您不需要复制
    y
    ,您只需复制py引用,因此
    x
    y
    指向同一个对象。当需要实际副本时,必须显式执行。例如,
    x=list(y)
    (对于列表)或
    x=y.copy()
    (对于dicts).我会记住这一点。据我所知,我在每个循环中都会引用一个新的dict;但是如果它与您的循环一起工作,它就足够用于此项目了。谢谢