Maxxx
Maxxx

Reputation: 3768

Writing files in python the correct way

I have a function that writes the content of list into a text file. For every element in the list, it writes the element into the text file, each having it's own new line.

def write_file(filename):
    name_file = filename
    filename = open(name_file, 'w')

    for line in list:
        if line == len(list)-1:
            filename.write(line)
        else:
            filename.write(line+'\n')
    filename.close()

i tend to notice a mistake where an empty newline is generated at the final line of a text file and I'm wondering if I am writing the file correctly?

Let's say my list contains [1,2,3,4] and writing it to the text file would give me

1
2
3
4
#in some cases, an empty newline is printed here at the end

I have no idea how to check if the write function is generating an extra line in the end due to the '\n' so I'll appreciate if anyone could give me some feedback.

Upvotes: 2

Views: 1954

Answers (6)

mhawke
mhawke

Reputation: 87054

Update:

@John Coleman has pointed out a misunderstanding. It seems that the last line should not have any new line character. This can be corrected by using enumerate() to provide a line count, checking whether it's the last line when printing, and varying the line end character accordingly:

def write_file(filename, data):
    with open(filename, 'w') as f:
        for line_no, item in enumerate(data, 1):
            print(item, file=f, end='\n' if line_no < len(data) else '')

This is not as elegant as using \n.join(data)` but it is memory efficient for large lists.

Alternative to join() is:

def write_file(filename, data):
    with open(filename, 'w') as f:
        print(*data, file=f, sep='\n', end='')

Original answer:

Why not simply use print() and specify the output file?

def write_file(filename, data):
    with open(filename, 'w') as f:
        for item in data:
            print(item, file=f)

Or more succinctly:

def write_file(filename, data):
    with open(filename, 'w') as f:
        print(*data, file=f, sep='\n')

The former is preferred if you have a large list because the latter needs to unpack the list to pass its contents as arguments to print().

Both options will automatically take care of the new line characters for you.

Opening the file in a with statement will also take care of closing the file for you.

You could also use '\n'.join() to join the items in the list. Again, this is feasible for smallish lists. Also, your example shows a list of integers - print() does not require that its arguments first be converted to strings, as does join().

Upvotes: 4

S.Ahmed
S.Ahmed

Reputation: 301

You shouldn't use for line in list here, list shouldn't be used for a list name because the word "list" is a reserved word for python. It's a keyword. You can do myLst = list("abcd") to obtain something like myLst=["a", "b", "c", "d"]

And about the solution to your problem, I recommend you use the with method in case you forget to close your file. That way, you won't have to close your file. Just exiting the indent will do the work. Here is how I have solved your problem:

#I just made a list using list comprehension method to avoid writing so much manually.
myLst=list("List number {}".format(x) for x in range(15))
#Here is where you open the file
with open ('testfile.txt','w') as file:
    for each in myLst:
        file.write(str(each))
        if each!=myLst[len(myLst)-1]:
            file.write('\n')
        else:
            #this "continue" command tells the python script to continue on to the next loop.
            #It basically skips the current loop.
            continue

I hope I was helpful.

Upvotes: 0

ABDERAHIM AMJIDA
ABDERAHIM AMJIDA

Reputation: 1

thefile = open('test.txt', 'w')

I'd use a loop:

for item in thelist:
  thefile.write("%s\n" % item)

Upvotes: -1

dalonlobo
dalonlobo

Reputation: 503

If you want to write to a file from list of strings, you can use the following snippet:

def write_file(filename):
    with open(filename, 'w') as f:
        f.write('\n'.join(lines))


lines = ["hi", "hello"]

write_file('test.txt')

Upvotes: 0

Jack
Jack

Reputation: 3057

Try

def write_file(filename):
    name_file = filename
    filename = open(name_file, 'w')

    for line in list:
        if line == list[-1]:
            filename.write(line)
        else:
            filename.write(line+'\n')
    filename.close()

In your example line == len(list)-1: you are just you are comparing an int the length of the list -1 instead of the last item in the list.

Although this is still not perfect as you could run into issues if you have repeating items in the list such as [1,2,3,5,2] in this case it would be best to use a join or a for i statement.

Upvotes: 0

hjpotter92
hjpotter92

Reputation: 80629

Instead of writing to the buffer so many times, do a .join, and write the result once:

with open(filename, 'w') as fp:
    fp.write('\n'.join(your_list))

Upvotes: 6

Related Questions