2

I´m writing a text adventure game as my first python program as suggested. I want to have a list of possible things a dog could eat, what´s bad about them, and how bad they are. So, I thought I´d do this:

badfoods = []
keys = ['Food','Problem','Imminent death']

food1 = ['alcohol', 'alcohol poisoning', 0]
food2 = ['anti-freeze', 'ethylene glycol', 1]
food3 = ['apple seeds', 'cyanogenic glycosides', 0] 

badfoods.append(dict(zip(keys,food1)))
badfoods.append(dict(zip(keys,food2))) 
badfoods.append(dict(zip(keys,food3))) 

There are actually around 40 foods I want to include. I know I can also do this:

[{'Food':'alcohol', 'Problem':'alcohol poisoning', 'Imminent death':0},
 {'Food':'anti-freeze', 'Problem':'ethylene glycol', 'Imminent death':1}
 {'Food':'apple seeds, 'Problem':'cyanogenic glycosides', 'Imminent death':0}] ] 

I also read this post on here about using YAML, which is appealing: What is the best way to implement nested dictionaries? but I still do not see how to avoid writing the keys a ton.

Plus, I am annoyed that I can´t figure out my original approach to avoiding writing the append 40 times, which is:

def poplist(listname, keynames, name):
    listname.append(dict(zip(keynames,name)))

def main():
    badfoods = []
    keys = ['Food','Chemical','Imminent death']

    food1 = ['alcohol', 'alcohol poisoning', 0]  
    food2 = ['anti-freeze', 'ethylene glycol', 1]
    food3 = ['apple seeds', 'cyanogenic glycosides', 0]
    food4 = ['apricot seeds', 'cyanogenic glycosides', 0]
    food5 = ['avocado', 'persin', 0]
    food6 = ['baby food', 'onion powder', 0]

    for i in range(5):
        name = 'food' + str(i+1)
        poplist(badfoods, keys, name)

    print badfoods
main()

I assume it doesn´t work because I am the for loop is creating a string and then feeding it to the function, and the function poplist doesn´t recognize it as a variable name. However, I don´t know if there´s a way to fix this or if I have to use YAML or write out the keys everytime. Any help is appreciated as I´m stumped!

Community
  • 1
  • 1
aprilcrash
  • 21
  • 4

3 Answers3

5

It's a bleepton easier if you just make it a single structure in the first place.

foods = [
  ['alcohol', 'alcohol poisoning', 0],
  ['anti-freeze', 'ethylene glycol', 1],
  ['apple seeds', 'cyanogenic glycosides', 0],
  ['apricot seeds', 'cyanogenic glycosides', 0],
  ['avocado', 'persin', 0],
  ['baby food', 'onion powder', 0]
]
badfoods = [dict(zip(keys, food)) for food in foods]
Ignacio Vazquez-Abrams
  • 699,552
  • 132
  • 1,235
  • 1,283
4

You were near:

>>> keys = ['Food','Chemical','Imminent death']
>>> foods = [['alcohol', 'alcohol poisoning', 0],
             ['anti-freeze', 'ethylene glycol', 1],
             ['apple seeds', 'cyanogenic glycosides', 0]]
>>> [dict(zip(keys, food)) for food in foods]
[{'Food': 'alcohol', 'Chemical': 'alcohol poisoning', 'Imminent death': 0}, {'Food': 'anti-freeze', 'Chemical': 'ethylene glycol', 'Imminent death': 1}, {'Food': 'apple seeds', 'Chemical': 'cyanogenic glycosides', 'Imminent death': 0}]
Roman Bodnarchuk
  • 26,469
  • 11
  • 56
  • 73
1

I'd suggest to follow best practices and separate data from code. Just store your the data in another file, using the format most suitable for your need. From what you've posted so far, CSV seems to be a natural choice.

# file 'badfoods.csv': 

Food,Problem,Imminent death
alcohol,alcohol poisoning,0
anti-freeze,ethylene glycol,1
apple seeds,cyanogenic glycosides,0

In your main program it takes only two lines to load it:

from csv import DictReader

with open('badfoods.csv', 'r') as f:
    badfoods = list(DictReader(f))
georg
  • 195,833
  • 46
  • 263
  • 351
  • The motivations for such "best practices" are not as strong in Python as in the languages they were really made for, imo. – Karl Knechtel Apr 25 '12 at 19:31
  • @KarlKnechtel: Lumping together code and data is a bad idea in any language. See this very question for an illustration. – georg Apr 25 '12 at 19:55