0

I have a sample.txt file:

1 7 14
3 3 10
1 1 3

What I wrote (it is wrong but at least something)(there were better ones, but I couldn't remake them):

content = []
with open ("sample.txt","r",encoding="utf-8") as file:
    for line in file:
        line = file.readline().strip().split(" ")
        mydict = {"A":int(file.readline().strip().split(" ")[0]),
                  "B":int(file.readline().strip().split(" ")[1]),
                  "C":int(file.readline().strip().split(" ")[2])}
        content.append(mydict)

print (content)

expected output:

[ {"A":1,"B":7,"C":14},{"A":3,"B":3,"C":10},{"A":1,"B":1,"C":3} ]

Neither of them worked sadly. There were 3 problems typically:

  • When I try to convert the values with int()
  • First or last line is missing (problem with indexing)
  • At the values I can't write just simply line[0], because that way it is not working (why?)

I am really newbie, maybe it will be good for someone else who is doing the same as me and noob like me.

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
Ilovemilk
  • 15
  • 3
  • Does this answer your question? [convert csv file to list of dictionaries](https://stackoverflow.com/questions/21572175/convert-csv-file-to-list-of-dictionaries) – buran Jan 10 '21 at 21:00
  • I hope this is a homework assignment, to teach you how to handle files and dictionaries. Otherwise, I'd suggest not to create such a list of dictionaries at all. – zvone Jan 10 '21 at 21:04
  • What you are missing is that `for line in file:` *already* reads the file a line at a time. Every call to `readline()` reads *another* line and so your input gets used up much quicker than you expect. Calling `readline()` is a lower-level (and older) approach that is an *alternative* to `for line in file:`. – BoarGules Jan 10 '21 at 21:14

4 Answers4

2

You are very close. The line variable is what you need:

content = []
with open ("sample.txt","r",encoding="utf-8") as file:
    for line in file:
        line = line.strip().split(" ")
        mydict = {"A":int(line[0]),
                  "B":int(line[1]),
                  "C":int(line[2])}
        content.append(mydict)

print (content)
quamrana
  • 37,849
  • 12
  • 53
  • 71
1

there is a builtin csv reader that takes care of this for you very easily

import csv

result = list(csv.DictReader(open("myfile.csv"),["A","B","C"],delimiter=" "))
Joran Beasley
  • 110,522
  • 12
  • 160
  • 179
0

The thing you are doing wrong is at

line = file.readline().strip().split(" ")

Here you are inside of a for that loops through each line. Check the output of the following

with open("sample.txt") as file:
    for line in file:
        print(line)

This will print each of the lines of the file. So on first iteration it will print 1 7 14 on the second 3 3 10 and on the third 1 1 3.

Now you are looping through each of the lines But while you are doing that you are reading the next line. Just check this out.

with open("sample.txt") as file:
    count = 0
    for line in file:
        print(count, "This is current line", line)
        print(count, "This is the next line",file.readline())
        count += 1 # count = count + 1

This simply outputs

0 This is current line 1 7 14
0 This is the next line 3 3 10
1 This is current line 1 1 3
1 This is the next line 

So what you are doing is you are going trhough 2 lines at a time and thus you are correctly getting an index error.

Instead what you will have to do is just remove all the readline and read one line at a time. This is almost the same as @quamrana snippet.

content = []
with open ("sample.txt","r",encoding="utf-8") as file:
    for line in file: # Only 1 line at a time
        line = line.strip().split(" ") # .strip() removes all white space in the begging and end and also newlines
        mydict = {"A":int(line[0]),
                  "B":int(line[1]),
                  "C":int(line[2])}
        content.append(mydict)
Countour-Integral
  • 1,138
  • 2
  • 7
  • 21
  • Thank you, now I understand this. But when you wrote line.split(" ").strip() it wasn't good. But when it is strip().split(" ") it works. Why? (One of methods makes it a list if I remember correctly) – Ilovemilk Jan 10 '21 at 21:39
  • You are correct `line.split(" ")` is a list and this is calling `.strip()` on a list. The `strip().split(" ")` is first a string then is split. This is my mistake. – Countour-Integral Jan 10 '21 at 21:41
0

in case you already using pandas:

import pandas as pd

df = pd.read_csv("sample.txt",sep=' ', header=None)
df.columns = ['A','B','C']
print(df.to_dict('records'))
adir abargil
  • 5,495
  • 3
  • 19
  • 29