Reputation: 11
I'm currently having a problem I cannot think through properly
I have a situation where I have a text file being read in a specific format
(predator) eats (prey)
What I am attempting to do is put it into a dictionary however there are situations where there are multiple lines of the.
(predator) eats (prey)
Where the same predator shows up to eat a different prey.
So far this is what it looks like...
import sys
predpraydic={}#Establish universial dictionary for predator and prey
openFile = open(sys.argv[1], "rt") # open the file
data = openFile.read() # read the file
data = data.rstrip('\n') #removes the empty line ahead of the last line of the file
predpraylist = data.split('\n') #splits the read file into a list by the new line character
for items in range (0, len(predpraylist)): #loop for every item in the list in attempt to split the values and give a list of lists that contains 2 values for every list, predator and prey
predpraylist[items]=predpraylist[items].split("eats") #split "eats" to retrive the two values
for predpray in range (0, 2): #loop for the 2 values in the list
predpraylist[items][predpray]=predpraylist[items][predpray].strip() #removes the empty space caued by splitting the two values
for items in range (0, len(predpraylist)
if
for items in range (0, len(predpraylist)): # Loop in attempt to place these the listed items into a dictionary with a key of the predator to a list of prey
predpraydic[predpraylist[items][0]] = predpraylist[items][1]
print(predpraydic)
openFile.close()
As you can see I simply dump the format into a list which I attempt to convert into a dictionary.
But this method will only accept one value for the key. And I want something that has two things like
Lion eats Zebra Lion eats dog
to have a dictionary that is
Lion: ['Zebra', 'Dog']
I cant think of a way of doing this. Any help would be appreciated.
Upvotes: 1
Views: 223
Reputation: 104722
There are two reasonable ways to go about making a dictionary that contains lists that you add to, rather than single items. The first is to check for an existing value before adding a new one. The second is to use a more sophisticated data structure, that takes care of creating the lists whenever it is necessary.
Here's a quick example of the first approach:
predpreydic = {}
with open(sys.argv[1]) as f:
for line in f:
pred, eats, prey = line.split() # splits on whitespace, so three values
if pred in predpreydic:
predpreydic[pred].append(prey)
else:
predpreydic[pred] = [prey]
A variation on this first approach replaces the if
/else
block with a slightly more subtle method call on the dictionary:
predpreydic.setdefault(pred, []).append(prey)
The setdefault
method sets predpredic[pred]
to an empty list if it doesn't already exist, then returns the value (either the new empty list, or the previous existing list). It works very similarly to the other approach to the problem, which is up next.
The second approach I mentioned involves the defaultdict
class from the collections
module (part of the Python standard library). This is a dictionary that creates a new default value any time you request a key that doesn't already exist. To create the values on demand, it uses a factory function that you provide when you first create the defaultdict
.
Here's what your program would look like using it:
from collections import defaultdict
predpreydic = defaultdict(list) # the "list" constructor is our factory function
with open(sys.argv[1]) as f:
for line in f:
pred, eats, prey = line.split()
predpreydic[pred].append(prey) #lists are created automatically as needed
Upvotes: 2