简体   繁体   English

Python:嵌套的iteritems循环仅运行一次

[英]Python : nested iteritems loop only run once

I'm trying to loop over a dictionary, and append dictionary inside it. 我正在尝试遍历字典,并在其中附加字典。 But when I use loop using iteritems(), it just iterating once and exit to the outer loop. 但是,当我使用带有iteritems()的循环时,它仅循环一次并退出外循环。 I am quite new in python but I think this code should be working. 我是python的新手,但我认为这段代码应该可以正常工作。

Why this happen? 为什么会这样?

from __future__ import division
import numpy
import pprint

training = {"outlook":{"sunny":{"yes":2,"no":3},"overcast":{"yes":4,"no":0},"rainy":{"yes":3,"no":2}},\
            "temperature":{"yes":[83,70,68,64,69,75,75,72,81],"no":[85,80,65,72,71]},\
            "humidity":{"yes":[86,96,80,65,70,80,70,90,75],"no":[85,90,70,95,91]},\
            "windy":{"false":{"yes":6,"no":2},"true":{"yes":3,"no":3}},\
            "play":{"yes":9,"no":5}}
processed = {}
total_yes = training["play"]["yes"]
total_no = training["play"]["no"]
total_all = training["play"]["no"]+training["play"]["yes"]

def main():
    for k,v in training.iteritems():
        if(k != "play"):
            for k2,v2 in v.iteritems():
                if((k2 == "yes") & isinstance(v2,list)):
                    processed[k] = {"yes":{"mean":numpy.mean(v2),"std":numpy.std(v2,ddof=1)}}
                elif((k2 == "no") & isinstance(v2,list)):
                    processed[k].update({"no":{"mean":numpy.mean(v2),"std":numpy.std(v2,ddof=1)}})
                else:
                    processed[k] = {}

                    # the problems start here
                    for i,j in v2.iteritems():
                        if(i == "yes"):
                            p_yes = j/total_yes
                            processed[k].update({k2:{"yes":p_yes,"no":(1-p_yes)}})
                        #when I print processed[k], it contains current value only (not including previous value)
                #suddenly exit after iterating once

        else:
            processed[k] = {"yes":total_yes/total_all,"no":total_no/total_all}

    pp = pprint.PrettyPrinter(indent=3)
    pp.pprint(processed)

if __name__ == '__main__':
    main()

The output is : 输出为:

...
'outlook': {  'sunny': {  'no': 0.7777777777777778,
                          'yes': 0.2222222222222222}},
...

But expected output is : 但是预期的输出是:

...
'outlook': {  'sunny': {  'no': 0.7777777777777778,
                          'yes': 0.2222222222222222}},
              'overcast': { 'no':xxxxx,
                            'yes':xxx
                          }
              ...
...

You're mistake was that you always erase the 'outlook' and in the end you see the last entry that was inserted into 'outlook' dictionary. 您错了,因为您总是擦除'outlook',最后看到插入到'outlook'词典中的最后一个条目。 Here is a fix of your code: 这是您的代码的修复:

from __future__ import division
import numpy
import pprint

training = {"outlook":{"sunny":{"yes":2,"no":3},"overcast":{"yes":4,"no":0},"rainy":{"yes":3,"no":2}},\
        "temperature":{"yes":[83,70,68,64,69,75,75,72,81],"no":[85,80,65,72,71]},\
        "humidity":{"yes":[86,96,80,65,70,80,70,90,75],"no":[85,90,70,95,91]},\
        "windy":{"false":{"yes":6,"no":2},"true":{"yes":3,"no":3}},\
        "play":{"yes":9,"no":5}}
processed = {}
total_yes = training["play"]["yes"]
total_no = training["play"]["no"]
total_all = training["play"]["no"]+training["play"]["yes"]


def main():
    for k,v in training.iteritems():
        if (k=='outlook'):
            pass
        if(k != "play"):
            for k2,v2 in v.iteritems():
                if((k2 == "yes") & isinstance(v2,list)):
                    processed[k] = {"yes":{"mean":numpy.mean(v2),"std":numpy.std(v2,ddof=1)}}
                elif((k2 == "no") & isinstance(v2,list)):
                    processed[k].update({"no":{"mean":numpy.mean(v2),"std":numpy.std(v2,ddof=1)}})
                else:
                    if k not in processed:
                        processed[k] = {}

                    for i,j in v2.iteritems():
                        if(i == "yes"):
                            p_yes = j/total_yes
                            processed[k].update({k2:{"yes":p_yes,"no":(1-p_yes)}})                       


        else:
            processed[k] = {"yes":total_yes/total_all,"no":total_no/total_all}

    pp = pprint.PrettyPrinter(indent=3)
    pp.pprint(processed)

if __name__ == '__main__':
    main()

The problem lies here: 问题出在这里:

else:
    processed[k] = {}

The previous value of k is overwritten as your for loop moves to the next element. 当您的for循环移至下一个元素时,先前的k值将被覆盖。

Define this here and your problem should be solved: 在这里定义这个,你的问题应该解决:

for k,v in training.iteritems():
    if(k != "play"):
        processed[k] = {}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM