Home > Blockchain >  Creating a nested dictionaries via for-loop
Creating a nested dictionaries via for-loop

Time:11-25

I'm having trouble creating a dictionary with multiple keys and values inside an other dictionary by using a for-loop.

I have a program that reads another text file, and then inputs it's information to the dictionaries. The file looks something like this:

GPU;GeForce GTX 1070 Ti;430
CPU;AMD Ryzen 7 2700X;233
GPU;GeForce GTX 2060;400
CPU;Intel Core i7-11700;360
RAM;HyperX 16GB;180
PSU;Corsair RM850X;210

What I'm trying to achieve is that I'm trying to create a dictionary for each component type {GPU, CPU, RAM, PSU, etc.} and to those I'm trying to input another dictionary, which consist from multiple keys and values which are {name1 : price1, name2 : price2, etc.} After running the program, the complete dictionary should look like this:

"GPU": {"GeForce GTX 1070 Ti": 430, "GeForce GTX 2060 2": 233},
"CPU": {"AMD Ryzen 7 2700X": 233, "Intel Core i7-11700 : 360},
"RAM": {"HyperX 16GB": 180},
"PSU": {"Corsair RM850X": 210}

But instead, it looks like this:

"GPU": {"GeForce GTX 2060 2": 233},
"CPU": {"Intel Core i7-11700 : 360},
"RAM": {"HyperX 16GB": 180},
"PSU": {"Corsair RM850X": 210}

Here is the problem: I can't create the dictionary properly, because new inner keys and values override each other. How can I make this loop not to do so, but instead just add the new values in the inner dict after each other?

Here's my code:

def main():
    filename = input("Enter the component file name: ")
    file = open(filename, mode="r")

    # Defining the outer dict. This dict's keys are the component types and
    # it's values are inner dictionaries.
    outer_dict = {}

    for row in file:
        row = row.strip()
        parts = row.split(";")

        # Defining variables for each part per line.
        type = parts[0]
        name = parts[1]
        price = int(parts[2])

        # Defining the inner dict. This dict's keys are the component's name
        # and it's price. There can be multiple names and prices in this dict.
        inner_dict = {}

        # Adding each name and price to the inner dictionaries.
        for i in range(1, len(parts)):
            inner_dict[name] = price

        # Adding the created inner dict into the outer dictionary.
        outer_dict[type] = inner_dict

    file.close()

if __name__ == "__main__":
    main()

Thank you all for your help in advance. It really is needed!

CodePudding user response:

It's this part

outer_dict[type] = inner_dict

You're replacing the value of your dictionary key. Instead change it to add a new sub-key like this

type = parts[0]
name = parts[1]
price = int(parts[2])
outer_dict[type][name] = price  # add `name` to the `type` dict as a new key

CodePudding user response:

You can simply achieve the expected behavior using collections.defaultdict and a simple loop.

NB. I am emulating a file with a split text here

f = '''GPU;GeForce GTX 1070 Ti;430
CPU;AMD Ryzen 7 2700X;233
GPU;GeForce GTX 2060;400
CPU;Intel Core i7-11700;360
RAM;HyperX 16GB;180
PSU;Corsair RM850X;210'''

from collections import defaultdict

out = defaultdict(dict)

for line in f.split('\n'):
    typ,name,price = line.split(';')
    out[typ][name] = price

dict(out)

output:

>>> dict(out)
{'GPU': {'GeForce GTX 1070 Ti': '430', 'GeForce GTX 2060': '400'},
 'CPU': {'AMD Ryzen 7 2700X': '233', 'Intel Core i7-11700': '360'},
 'RAM': {'HyperX 16GB': '180'},
 'PSU': {'Corsair RM850X': '210'}}

CodePudding user response:

For outer_dict you can use defaultdict from collections, making {} the default value. That way you can simply do outer_dict[type][name] = price for each line

  • Related