I am working on a function that convert a multi-level dictionary to a list of one-level dictionaries.
The logic seems right. But when I run it, the while loop runs infinity. I found the first time it went into the while loop, next_level.pop() was working. Starting from the second time of the while loop, the pop() function never remove the last item of next_level. I also tried to retrieve the last item by next_level[-1], and delete the last item by del next_level[-1]. But the result is the same. I think it could be related to the reference thing. Any idea?
def flat_dict(self, params):
"""convert a multi-level dictionary to a list of one-level dictionaries"""
plist = next_level = []
next_level.append(params)
while next_level:
current_level = temp_level = next_level.pop()
for k, v in current_level.iteritems():
if isinstance(v, dict):
next_level.append(temp_level.pop(k))
pk = [x for x in next_level[-1].keys() if x.endswith('_id')]
temp_level[pk[0]] = next_level[-1][pk[0]]
plist.append(temp_level)
return plist
Without an example of the dictionary, its a little hard to visualize…but generally for a case like this, I’d recommend recursion anyway:
In direct answer to your question tho, I’m not 100% sure what is going wrong – I can say that pop() itself will work just fine. I’m guessing it has to do with the way you’re initializing the plist, are you getting an infinite loop?
This line is actually setting plist and next_level to the same exact list – not initializing a blank list for each variable.
When you modify plist, later in your loop, you’re actually modifying the next_level also which is not what is intended is my guess…try defining your plist/next_level this way:
And see what happens.