lulu
lulu

Reputation: 183

How to add newline to text file in comprehensive nested list?

I have a nested list:

A = [['a', 'b', 'c', 'd', 'e'], ['a', 'a', 'b', 'c'], ['b', 'c'], ['a', 'd']]

I want to save list A to multiple text files with the limitation of 2 nested list per text file.

So the output should be like:

in small_file_2.txt:

a
b
c
d
e

a
a
b
c

in small_file_4.txt:

b
c

a
d

I tried this code:

lines_per_file = 2
for lineno, line in enumerate(A):
    if lineno % lines_per_file == 0:
        if smallfile:
           smallfile.close()
        small_filename = 'small_file_{}.txt'.format(lineno + lines_per_file)
        smallfile = open(small_filename, "w")
     smallfile.write('\n'.join(str(x) for x in line)+'\n')         
smallfile.close()

Unfortunately, the output in text files are not as I expected it to be. It does not print the newline for after every new nested list.

Upvotes: 1

Views: 251

Answers (3)

sudhirkoda
sudhirkoda

Reputation: 11

Below code will work fine as per your requirement.

lines_per_file = 2
for lineno, line in enumerate(A):
    if lineno % lines_per_file == 0:
        small_filename = 'small_file_{}.txt'.format(lineno + lines_per_file)
    smallfile = open(small_filename, "a")
    smallfile.write('\n'.join(str(x) for x in line)+'\n')
    smallfile.write('\n')
    smallfile.close()
smallfile.close()

Upvotes: 1

h4z3
h4z3

Reputation: 5478

Second approach with with and no empty lines at the end:

lines_per_file = 2
for lineno in range(0, len(A), lines_per_file):
    small_filename = 'small_file_{}.txt'.format(lineno + lines_per_file)
    with smallfile = open(small_filename, "w"): #this will close the file by itself
        smallfile.write('\n\n'.join('\n'.join(str(x) for x in A[current])) for current in range(lineno, min(lineno+lines_per_file, len(A)))

Let's explain the magic:

for lineno in range(0, len(A), lines_per_file):

We'll be taking all lines from 0 to lines_per_file-1, then lines_per_file to 2*lines_per_file-1... Until the end.

'\n'.join(str(x) for x in A[current])

This is what you used, but we call the line directly from A. Parses one line as single characters in multiple lines.

'\n\n'.join(...)

Parsed lines will have two linebreaks between each other - that means there will be an empty line you wanted.

for current in range(lineno, min(lineno+lines_per_file, len(A))

As I said, we are taking lines from lineno (that is: 0, lines_per_file, 2*lines_per_file...) until the next step. Or until the end of the A, whichever is shorter (that's why there's min).

Upvotes: 1

tituszban
tituszban

Reputation: 5152

The fix is fairly simple:

\n.join([]) adds \nbetween every item, but not before and after. The first \n you've added just added one afterwards. If you want it separated, you need a second one.

lines_per_file = 2
for lineno, line in enumerate(A):
    if lineno % lines_per_file == 0:
        if smallfile:
           smallfile.close()
        small_filename = 'small_file_{}.txt'.format(lineno + lines_per_file)
        smallfile = open(small_filename, "w")
    smallfile.write('\n'.join(str(x) for x in line)+'\n\n')         # <= add a second \n
smallfile.close()

Upvotes: 2

Related Questions