Question

Problem part of the code:

while counter < length:
    if something:
    else:
        for key,value in dictionary.items():
            if something:
            else:
    counter += 1

The structure is a { key:[ {key:value,key1:value1}, {key:value,key1:value1} ] } which is what the counter (list index) is for.

So I've noticed this a few times in some scripts I've written while I've been teaching myself Python (3.2.3).

I tried searching but no luck (maybe my search terms are wrong, who knows?) and I've checked the documentation and what seems to be the problem is that for while statements it says, "The while statement is used for repeated execution as long as an expression is true". And for For statements it says, "The expression list is evaluated once".

Now when my script runs it keeps getting a key error because the counter has increased by 1; but the for statements isn't updating to reflect the new elements from the list which is another dictionary; it's still using the first element.

I assumed that each iteration in the while loop would cause the For statement to re-evaluate. Apparently I was wrong on that count.

Now I can rewrite the code, to fix this, but what I'd like to know as I've ran into this a few times already, is how can I use a For loop in a while statement in this fashion but have it re-evaluate the For statement on each iteration through the while loop.

Thanks!

Updated: I've added the actual code below. It wouldn't surprise me if I'm just doing something wrong. I was watching the values in the debugger, and when count changed from 0 to 1, it started on the next iteration of the while loop. From there everything went as it should, until it hit the For loop "for key,value in item.items():", and the values for item.items() didn't change at all. Updated Update: After trying to figure it out I'm pretty sure it's the for item in v: that's causing the problem. Let's see if I can figure it out!

Fixed! Problem was with the For item in v: that was outside the while loop, solved by moving it into the loop.

def checkDifferences(newFile,oldFile):
    resultDiff = []
    for k,v in newFile.items():
        if newFile[k] != oldFile[k]:
            for item in v:
                count = 0
                lengthList = len(newFile[k])
                newKeys = newFile[k][count].keys()
                oldKeys = oldFile[k][count].keys()                
                while count < lengthList:
                    if newKeys == oldKeys:
                        for key,value in item.items():
                            newValue = newFile[k][count][key] 
                            oldValue = oldFile[k][count][key]
                            if newValue == oldValue:
                                pass
                            else:
                                resultDiff.append((k,count,key, oldValue,newValue))
                    else:
                        newValue = list(newFile[k][count].keys())
                        oldValue = list(oldFile[k][count].keys())
                        keyList = [key for key in newValue if key not in oldValue]
                        print(keyList)
                        for key,value in item.items():
                            if key in keyList:
                                oldValue = oldFile[k][count][oldKey]
                                resultDiff.append((k,count,key, None,newValue))
                            else:
                                oldValue = oldFile[k][count][key]
                            newValue = newFile[k][count][key]
                            if newValue == oldValue:
                                pass
                            else:
                                resultDiff.append((k,count,key, oldValue,newValue))
                            oldKey = key
                    count += 1
     return resultDiff
Was it helpful?

Solution

The expression in the for statement is evaluated once each time the for loop begins. Since you've put the for loop into a while loop, each time around the while loop, when the for statement is encountered, the expression will be evaluated.

There is something else wrong with your code. Post a real code sample.

OTHER TIPS

My guess is that believe the OP may want to loop over the 'dict's contained in a primary dictionary and the following is meant to be the general flow.

list_of_dicts = dictionary['key']
for subdict in list_of_dicts:
    print subdict.items() # or whatever

Your question seems a little vague to me, but based your comments about the format of the structure and the sample code, something along the following lines would allow you to process its contents:

# for structure { key:[ {key:value,key1:value1}, {key:value,key1:value1}, ... ] }

for dict_list in structure.values():
    if something:
    else:
        for key,value in dict_list.items():
            if something:
            else:

The inner for loop will be evaluated each time another list of dictionaries is retrieved from the outer structure dictionary. I used structure.values() because you don't seem to be interested in what structure's keys are. Each of structure's keys appears to be associated with value which is a list of dictionaries, the dict_list variable used in the code above.

In Python needing a counter or loop index is frequently unnecessary to process the contents of containers such as lists or dictionaries because you can iterate over them directly with a for as shown.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top