B.Joelene
B.Joelene

Reputation: 133

Manipulating data of file several times

I'm having a little bit trouble with file operations.. I want to manipulate data 2 times and write the last manipulated data into same file.

This is my manipulated file:

['Simon', 93.45000000000002, 'AA']
['Jane', 87.55000000000001, 'BA']
['Peter', 85.95, 'BA']

And here is my code for how to change data in file.

for line in manipulated_file:
    line=line.split()
    list_to_be_written=[]
    for i in line:
        i=i.replace("['","")
        i=i.replace("'","")
        i=i.replace(",",":")
        i=i.replace("]","")
        list_to_be_written.append(i)
    list_to_be_written=" ".join(list_to_be_written)
    print list_to_be_written

It runs perfecly how ever i can't write the output to the file..

Expected output in the same file:

Simon: 93.45000000000002: AA
Jane: 87.55000000000001: BA
Peter: 85.95: BA

Thank you in advance.

Upvotes: 2

Views: 63

Answers (3)

Padraic Cunningham
Padraic Cunningham

Reputation: 180391

You can use ast.literal_eval to parse the lists and fileinput.input to change the original file.

import fileinput
from ast import literal_eval
import sys


for line in fileinput.input("in.txt", inplace=1):
    sys.stdout.write(": ".join(map(str, literal_eval(line))) + "\n")

Which will give you:

Simon: 93.45000000000002: AA
Jane: 87.55000000000001: BA
Peter: 85.95: BA

You can also do it by just splitting and stripping:

import fileinput
import sys
for line in fileinput.input("in.txt", inplace=True):
    sys.stdout.write(":".join([w.strip("'") for w in line.strip("[]\n").split(", ")]) + "\n"

Which gives you the same output:

Simon: 93.45000000000002: AA
Jane: 87.55000000000001: BA
Peter: 85.95: BA

If the code happened to error you would lose data so a better option may be to write to a tempfile and then do a shutil.move:

from shutil import move
from tempfile import NamedTemporaryFile

with open("in.txt") as f, NamedTemporaryFile("w", dir=".", delete=False) as tmp:
    for line in f:
        tmp.write(": ".join([w.strip("'") for w in line.strip("[]\n").split(", ")]) + "\n")

move(tmp.name,"in.txt")

Upvotes: 2

Ilya V. Schurov
Ilya V. Schurov

Reputation: 8047

I believe that if you want your data will be written into the same file as the initial data, you have to open it first for reading, read into variable, process it, then open it for writing and write down everything that is needed. See the docs for details.

with open("file.txt", "r") as manipulated_file:
    manipulated_file_lines = manipulated_file.readlines()
with open("file.txt", "w") as  manipulated_file:

    for line in manipulated_file_lines:
        line=line.split()
        list_to_be_written=[]
        for i in line:
            i=i.replace("['","")
            i=i.replace("'","")
            i=i.replace(",",":")
            i=i.replace("]","")
            list_to_be_written.append(i)
        list_to_be_written=" ".join(list_to_be_written)
        print list_to_be_written

        manipulated_file.write(list_to_be_written)

P.S. I'm not sure that you have to process your lines manually in this way. I believe it is better to convert them to Python object (e.g. list) with json decoder, then format output string from that object. This can be used instead of those .replace()'s:

import json
with open("file.txt", "r") as manipulated_file:
    manipulated_file_lines = manipulated_file.readlines()
with open("file.txt", "w") as  manipulated_file:
    for line in manipulated_file_lines:
        processed_list = json.loads(line.replace("'",'"'))
        list_to_be_written=": ".join(map(str,processed_list))
        # this should be tweaked if you want full precision for numbers

        print list_to_be_written

        manipulated_file.write(list_to_be_written)

You can also use ast.literal_eval instead of json.loads, see the docs and this question.

Upvotes: 1

Ahasanul Haque
Ahasanul Haque

Reputation: 11134

You can use ast.literal_eval

from ast import literal_eval

with open('demo.txt','r') as input_file, open('output.txt','a') as output:
    for line in input_file:
        temp = literal_eval(line)
        output.write(": ".join([repr(a) if type(a)== float else a for a in temp])+'\n')

Content of output.txt:

Simon: 93.45000000000002: AA
Jane: 87.55000000000001: BA
Peter: 85.95: BA

Upvotes: 3

Related Questions