Reputation: 21
I need to write a function, shuffleFiles(afile, bfile, cfile), that reads a line from file afile then reads a line from file bfile and appends these lines respectively to file C. If either file afile or bfile has been completely read then continue appending lines from the other file into file C.
This is the code I have so far, the lines are not being written to the file, but if i swap them out for print statements the lines print out in the correct order, just with blank \n in between most of them. not sure where to go from here
def shuffleFiles(afile, bfile, cfile):
fileA = open(afile, 'r')
fileB = open(bfile, 'r')
fileC = open(cfile, 'a')
fileADone = False
fileBDone = False
while not fileADone or not fileBDone:
if not fileADone:
line = fileA.readline()
line.rstrip()
line.strip()
if line == "" or line == " " or line == "/n":
fileADone = True
else:
fileC.write(str(line))
if not fileBDone:
line = fileB.readline()
line.rstrip()
line.strip()
if line == "" or line == " " or line == "/n":
fileBDOne = True
else:
fileC.write(str(line))
fileA.close()
fileB.close()
fileC.close()
Upvotes: 2
Views: 273
Reputation: 24788
Here's one way to iterate over two alternating iterables (files included):
from itertools import chain, izip_longest
fileA = open('file_A.txt')
fileB = open('file_B.txt')
for line in filter(None, chain.from_iterable(izip_longest(fileA, fileB))):
#Do stuff here.
The izip_longest
"zips" together two or more iterables:
>>> a = [1, 2, 3, 4]
>>> b = ['a', 'b', 'c', 'd', 'e', 'f']
>>> list(izip_longest(a, b))
[(1, 'a'), (2, 'b'), (3, 'c'), (4, 'd'), (None, 'e'), (None, 'f')]
Then chain.from_iterable
chains these into one long running iterable:
>>> list(chain.from_iterable(izip_longest(a, b)))
[1, 'a', 2, 'b', 3, 'c', 4, 'd', None, 'e', None, 'f']
Finally, filter
with None
as the first argument only returns the values with non-false values. In this case, it serves to filter out the None
s in the list above (Nones
will occur when one iterable is longer than another), as well as to filter out ''
empty strings that may be present in the files.
>>> filter(None, chain.from_iterable(izip_longest(a, b)))
[1, 'a', 2, 'b', 3, 'c', 4, 'd', 'e', 'f']
EDIT - Thanks to Tadeck
Putting all of this together, along with the more pythonic with
operator for opening files, we get something like this:
with open('fileA.txt') as fileA, open('fileB.txt') as fileB, open('fileC.txt') as fileC:
lines = chain.from_iterable(izip_longest(fileA, fileB, fillvalue=''))
fileC.writelines(filter(None, (line.strip() for line in lines)))
Upvotes: 1