skip to Main Content

When I create a multi level dictionary (or JSON) I have to initialize at each level and it overwrites the old data

For example I’d like to create

dict1 = {}
for i in ["i","you"]:
    for j in ["have", "has", "had"]:
        for k in ["a","an"]:
            for m in ["apple", "pear"]:
                for n in ["cat","dog"]:
                    dict1[i] = {j:{k:{"fruit":m,"animal":n}}} 
print(dict1)

I would like to have the result of

{'i': {'have': {'a': {'fruit': 'apple', 'animal': 'cat'}}},
 'you': {'have': {'a': {'fruit': 'apple', 'animal': 'dog'}}}

and so on. However I am receiving only the last 2 permutations as they always get overwritten.

2

Answers


  1. You are overriding the key every iteration of the inner loops. Use a list instead

    lst = []
    for i in ["i", "you"]:
        for j in ["have", "has", "had"]:
            for k in ["a", "an"]:
                for m in ["apple", "pear"]:
                    for n in ["cat", "dog"]:
                        lst.append({i: {j: {k: {"fruit": m, "animal": n}}}})
    
    print(lst)
    

    Output

    [{'i': {'have': {'a': {'fruit': 'apple', 'animal': 'cat'}}}},
     {'i': {'have': {'a': {'fruit': 'apple', 'animal': 'dog'}}}},
     {'i': {'have': {'a': {'fruit': 'pear', 'animal': 'cat'}}}},
     ...
     {'you': {'had': {'an': {'fruit': 'apple', 'animal': 'dog'}}}},
     {'you': {'had': {'an': {'fruit': 'pear', 'animal': 'cat'}}}},
     {'you': {'had': {'an': {'fruit': 'pear', 'animal': 'dog'}}}}]
    

    Edit

    You can keep the dict format if you add an additional unique key

    dict1 = {}
    id = 0
    for i in ["i", "you"]:
        for j in ["have", "has", "had"]:
            for k in ["a", "an"]:
                for m in ["apple", "pear"]:
                    for n in ["cat", "dog"]:
                        dict1[id] = {i: {j: {k: {"fruit": m, "animal": n}}}}
                        id += 1
    

    Output

    {0: {'i': {'have': {'a': {'fruit': 'apple', 'animal': 'cat'}}}},
     1: {'i': {'have': {'a': {'fruit': 'apple', 'animal': 'dog'}}}},
     2: {'i': {'have': {'a': {'fruit': 'pear', 'animal': 'cat'}}}},
    ...
     45: {'you': {'had': {'an': {'fruit': 'apple', 'animal': 'dog'}}}},
     46: {'you': {'had': {'an': {'fruit': 'pear', 'animal': 'cat'}}}},
     47: {'you': {'had': {'an': {'fruit': 'pear', 'animal': 'dog'}}}}}
    

    Edit 2:

    Keys in dict must be unique, you can’t have i key more than once. If you don’t want to use one of the above options the only other way is to use a tuple as the key#

    dict1 = {}
    for i in ["i", "you"]:
        for j in ["have", "has", "had"]:
            for k in ["a", "an"]:
                dict1[(i, j, k)] = {"fruit": "apple", "animal": "dog"}
    print(dict1[('i', 'have', 'a')]) # {'fruit': 'apple', 'animal': 'dog'}
    print(dict1[('i', 'have', 'an')]) # {'fruit': 'apple', 'animal': 'dog'}
    

    You will still have the issue duplicate keys in the inner loops of fruit and animal (if you really need them), to get all the options you will still need a list

    dict1 = {}
    for i in ["i", "you"]:
        for j in ["have", "has", "had"]:
            for k in ["a", "an"]:
                dict1[(i, j, k)] = []
                for m in ["apple", "pear"]:
                    for n in ["cat", "dog"]:
                        dict1[(i, j, k)].append({"fruit": m, "animal": n})
    
    print(dict1[('i', 'have', 'a')])
    print(dict1[('i', 'have', 'an')])
    
    # [{'fruit': 'apple', 'animal': 'cat'}, {'fruit': 'apple', 'animal': 'dog'}, {'fruit': 'pear', 'animal': 'cat'}, {'fruit': 'pear', 'animal': 'dog'}]
    # [{'fruit': 'apple', 'animal': 'cat'}, {'fruit': 'apple', 'animal': 'dog'}, {'fruit': 'pear', 'animal': 'cat'}, {'fruit': 'pear', 'animal': 'dog'}]
    
    Login or Signup to reply.
  2. Creating in one shot a nested structure requires a good initialization at each level.
    In your approach you can adopt defaultdict

    from collections import defaultdict
    
    tree = lambda: defaultdict(tree)
    dict1 = tree()
    
    for i in ["i","you"]:
        for j in ["have", "has", "had"]:
            for k in ["a","an"]:
                for m in ["apple", "pear"]:
                    for n in ["cat","dog"]:
                        dict1[i][j][k] = {"fruit":m,"animal":n}
    

    The output is not exactly a dict, but works in the same way.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search