-1

I'm current working a script that takes an Android application's metadata as a nested dictionary and inserts it to MongoDB. However, since some of the keys include '.'s (due to component names in the APK file), which unfortunately isn't accepted by MongoDB in the version being dealt with. Currently trying to write a recursive script which replace the '.'s to '/'s of the keys in the dict data being inserted, but some keys still aren't changed to fit the requirements.

def fixKeys(dictionary):
    for k,v in dictionary.items():
        if isinstance(v, dict):
            if '.' in k:
                dictionary[k.replace('.','/')] = dictionary.pop(k)
            fixKeys(v)
        else:
            if '.' in k:
                dictionary[k.replace('.','/')] = dictionary.pop(k)
    return dictionary 

Example input:

data = {"gender":"male","name.data": {"last.name":"Arabulut","first.name":"Altay","parents.names":{"father.name":"John","mother.name":"Jennifer"}}, "birthday.data":{"birthday.day":"01","birthday.month":"03","birthday.year":"1977"}}

Any idea as to what might be missing?

  • 1
    Can you add an example input where this is not working? – g_bor Sep 20 '20 at 17:35
  • The first two lines inside your if statement are exactly the same. You could move them above the `if` to avoid duplication. – mousetail Sep 20 '20 at 18:16
  • I see in the edit history that you edited the code and removed the failing example. Did you fix your code? Is your problem solved? If so, could you post an answer to your own question so that people can see that? After 2 days, you'll even be able to accept your own answer. If another answer solved your problem, you could instead just accept that answer. – Brian McCutchon Sep 20 '20 at 18:18
  • @BrianMcCutchon I've updated the example to show a more similar one to the one I'm working with as the previous one did not fully indicate the nature of the data – Altay Arabulut Sep 20 '20 at 19:19

1 Answers1

1

after the editing I understood your question more properly, the recursion solution for unknown amount of nested dicts is as below:

def fixKeys(dictionary):
    for k,v in list(dictionary.items()):
        if isinstance(v, dict):
            dictionary[k.replace('.', '/')] = fixKeys(v)
        else:
            dictionary[k.replace('.', '/')] = v
        if "." in k:
            dictionary.pop(k)
    return dictionary

m_dict = {"gender":"male", "name.data": {"last.name":"Arabulut","first.name":"Altay","parents.names":{"father.name":"John","mother.name":"Jennifer"}}, "birthday.data":{"birthday.day":"01","birthday.month":"03","birthday.year":"1977"}}

new_dict = fixKeys(m_dict)
print(str(new_dict))

output:

{'gender': 'male', 'name/data': {'last/name': 'Arabulut', 'first/name': 'Altay', 'parents/names': {'father/name': 'John', 'mother/name': 'Jennifer'}}, 'birthday/data': {'birthday/day': '01', 'birthday/month': '03', 'birthday/year': '1977'}}

very good question. like the coding and debugging!

Yossi Levi
  • 1,258
  • 1
  • 4
  • 7
  • Forgot to mention the dict is nested, sorry about that :( – Altay Arabulut Sep 20 '20 at 17:45
  • What if there are key, value pairs that do not have a `'.'`, e.g there is `{"gender":"male"}` in the data? From what I tried, it does not account for those and they are not in the final output – Altay Arabulut Sep 20 '20 at 19:13
  • you right, fixed it to remove the key only if `.` in it. your main issue was that your dictionary actually changed size on each iteration because when you insert like that: `dictionary[k.replace('.', '/')] = v`, the length of your dict increased, because insertion of key+value to dictionary actually replacing value if key exist, and create new if dont, in that case it create new - because it didnt exist. – Yossi Levi Sep 20 '20 at 19:24
  • accept or upvote would be appreciated if my answer helped you – Yossi Levi Sep 20 '20 at 19:25
  • I can't upvote just yet, but this was the answer I was looking for. Thanks :) – Altay Arabulut Sep 20 '20 at 19:39