user4329673
user4329673

Reputation:

appending a list from a read text file python3

I am attempting to read a txt file and create a dictionary from the text. a sample txt file is:

John likes Steak

John likes Soda

John likes Cake

Jane likes Soda

Jane likes Cake

Jim likes Steak

My desired output is a dictionary with the name as the key, and the "likes" as a list of the respective values:

{'John':('Steak', 'Soda', 'Cake'), 'Jane':('Soda', 'Cake'), 'Jim':('Steak')}

I continue to run into the error of adding my stripped word to my list and have tried a few different ways:

pred = ()

prey = ()

spacedLine = inf.readline()

line = spacedLine.rstrip('\n')

while line!= "":

    line = line.split()
    pred.append = (line[0])
    prey.append = (line[2])
    spacedLine = inf.readline()
    line = spacedLine.rstrip('\n')

and also:

spacedLine = inf.readline()

line = spacedLine.rstrip('\n')

while line!= "":

     line = line.split()      
     if line[0] in chain:
       chain[line[0] = [0, line[2]]
      else:
        chain[line[0]] = line[2]
    spacedLine = inf.readline()
    line = spacedLine.rstrip('\n')

any ideas?

Upvotes: 0

Views: 98

Answers (3)

vks
vks

Reputation: 67998

dic={}

for i in f.readlines():
    if i:
        if i.split()[0] in dic.keys():
            dic[i.split()[0]].append(i.split()[2])
        else:
            dic[i.split()[0]]=[i.split()[2]]

print dic

This should do it.

Here we iterater through f.readlines f being the file object,and on each line we fill up the dictionary by using first part of split as key and last part of split as value

Upvotes: 0

martineau
martineau

Reputation: 123531

This will do it (without needing to read the entire file into memory first):

likes = {}
for who, _, what in (line.split()
                        for line in (line.strip()
                            for line in open('likes.txt', 'rt'))):
    likes.setdefault(who, []).append(what)

print(likes)

Output:

{'Jane': ['Soda', 'Cake'], 'John': ['Steak', 'Soda', 'Cake'], 'Jim': ['Steak']}

Alternatively, to simplify things slightly you could use a temporarycollections.defaultdict:

from collections import defaultdict

likes = defaultdict(list)
for who, _, what in (line.split()
                        for line in (line.strip()
                            for line in open('likes.txt', 'rt'))):
    likes[who].append(what)

print(dict(likes))  # convert to plain dictionary and print

Upvotes: 2

9000
9000

Reputation: 40904

Your input is a sequence of sequences. Parse the outer sequence first, parse each item next.

Your outer sequence is:

Statement
<empty line>
Statement
<empty line>
...

Assume that f is the open file with the data. Read each statement and return a list of them:

def parseLines(f):
  result = []
  for line in f:  # file objects iterate over text lines
    if line:  # line is non-empty
      result.append(line)
  return result

Note that the function above accepts a much wider grammar: it allows arbitrarily many empty lines between non-empty lines, and two non-empty lines in a row. But it does accept any correct input.

Then, your statement is a triple: X likes Y. Parse it by splitting it by whitespace, and checking the structure. The result is a correct pair of (x, y).

def parseStatement(s):
  parts = s.split()  # by default, it splits by all whitespace
  assert len(parts) == 3, "Syntax error: %r is not three words" % s
  x, likes, y = parts  # unpack the list of 3 items into varaibles
  assert likes == "likes", "Syntax error: %r instead of 'likes'" % likes
  return x, y

Make a list of pairs for each statement:

pairs = [parseStatement(s) for s in parseLines(f)]

Now you need to group values by key. Let's use defaultdict which supplies a default value for any new key:

from collections import defaultdict

the_answer = defaultdict(list)  # the default value is an empty list

for key, value in pairs:
  the_answer[key].append(value) 
  # we can append because the_answer[key] is set to an empty list on first access

So here the_answer is what you need, only it uses lists as dict values instead of tuples. This must be enough for you to understand your homework.

Upvotes: 1

Related Questions