Search code examples
pythonlistfor-loopdictionaryreadline

Python: Read multiple lines from a file and make instances stored in an dictionary


My struggle:

Reading two lines and jumping over the third.

Then I want to store all the objects in a dictionary with the name as keys.

**** Ingredients.txt ****
Name1
ingredient1/ingredient2/ingredient3

Name2
ingredient1/ingredient2

Name3
...

class Foodset(object):
    def __init__(self, name):
        self.name = name
        self.ingredients = set([])

    def __str__(self):
        return str(self.name) + ' consits of: ' + ", ".join(str(e) for e in self.ingredients) + '.'

    def setIngredients(self, list):
        for i in list:
            self.ingredients.add(i)

def getMenu(file="ingredients.txt"):
    with open(file, 'r') as indata:
        menu = dict()
        for line in indata:
            tempString = str(line.rstrip('\n'))
            menu[tempString] = Foodset(tempString)

I want to read the next line and store as ingredients and then skip the third line since it's blank. Then repeat.

The problem I'm having with the for loop is that I can't store two different lines in the same loop and then refer to the same object in order to use the setIngredients() method. What other ways can I read multiple lines inside each loop?

EDIT: @Arpan came up with a quick solution to use indata.readlines() to make a list of every line and loop with steps of 3 while storing first and second value and skipping the third.

I just came up with an other solution using the readline() method 3 times inside a while loop. Using readline() is what I originally wanted.

def getMenu(menu="ingredients.txt"):
    with open(menu, "r") as indata:
        menu = dict()
        while True:
            name = indata.readline().strip('\n')
            ingredientList = indata.readline().strip().split('/')
            if name == "":
                break
# here I just added a parameter that directly set the attribute "ingredients" inside the object.
            menu[name] = Foodset(name, ingredientList)
            indata.readline()
    return menu
    

Solution

  • Try something like this.

    with open(file, 'r') as indata:
        lines = indata.readlines()
    menu = dict()
    for i in xrange(0, len(lines), 3):
        name = lines[i].rstrip('\n')
        ingredients = lines[i+1].rstrip('\n').split('/')
        f = Foodset(name)
        f.setIngredients(ingredients)
        menu[name] = f
    

    For python 3.x use range instead of xrange.