0

I try to convert a given python dictionary to a pair of values: a list of keys and the item the keys are pointing to:

['key 1', 'key 2', .. , 'key n'], item

I found the 'flatten_dict_to_string'-function, wich does the job perfecty. Except: it has a string of keys as its output, not a list.

So I modified it to generate a list. But after my small change I'm getting a totally different result. Now, several hours and a whole bunch of ideas later, I've got stuck. Where's my mistake?

Test-data
 {'A': 'a',
  'B': {'B1': 'b1',
        'B2': 'b2',
        'B3': {'B31': 'b31'},
        'B4': 'b4'},
  'C': 'c'}

Keystring - from 'flatten_dict_to_string'-function - works perfectly
A a
B_B1 b1
B_B2 b2
B_B3_B31 b31
B_B4 b4
C c

Keylist - from my 'flatten_dict_to_list'-function - works not so perfectly :-(
['A'] a
['A', 'B', 'B1'] b1
['A', 'B', 'B1', 'B2'] b2
['A', 'B', 'B1', 'B2', 'B3', 'B31'] b31
['A', 'B', 'B1', 'B2', 'B3', 'B31', 'B4'] b4
['A', 'B', 'B1', 'B2', 'B3', 'B31', 'B4', 'C'] c

Expected Keylist
['A'] a
['B', 'B1'] b1
['B', 'B2'] b2
['B', 'B3', 'B31'] b31
['B', 'B4'] b4
['C'] c

The code:

def flatten_dict_to_string(data, keystring=''): # perfect working
    if type(data) == dict:
        keystring = keystring + '_' if keystring else ''
        for key in data:
            #---------------------------- adding the current key to the string
            yield from flatten_dict_to_string(data[key], keystring + str(key)) 
    else:
        yield keystring, data

def flatten_dict_to_list(data, keylist=[]): # everything apart from perfect
    if type(data) == dict:
        for key in data:
            #---------------------------- adding the current key to the list           
            keylist.append(key) 
            yield from flatten_dict_to_list(data[key], keylist)
    else:
        yield keylist, data
#        keylist.clear() #--- when uncommented the first key is missing

data = {"A": 'a',
        "B":{
            "B1": "b1",
            "B2": "b2",
            "B3":{
                "B31": "b31"},
            "B4": "b4"},
        "C": 'c'}


print('\nData\n',data)

print('\nKeystring')
for k,v in flatten_dict_to_string(data):
    print(k,v)

print('\nKeylist')
for k,v in flatten_dict_to_list(data):
    print(k,v)

print("\nExpected Keylist\n['A'] a\n['B', 'B1'] b1\n['B', 'B2'] b2\n['B', 'B3', 'B31'] b31\n['B', 'B4'] b4\n['C'] c")

Any ideas?

its_me
  • 5
  • 3
  • 1
    You will notice that the pattern in what's wrong with your output is that the list shows *all the previous list contents*, plus the correct values. The reason for this is that the previous data *was already there* - because it is *the same list, every time*. The reason for *that* is explained in the linked duplicate. – Karl Knechtel Aug 08 '21 at 20:37
  • The general technique of using a recursive generator to get output from a tree structure is a good one. However, it's important to be especially careful with mutable data in recursive algorithms. – Karl Knechtel Aug 08 '21 at 20:38

0 Answers0