Learning is a mess
Learning is a mess

Reputation: 8277

From files to list of lines

I know how to extract lines from a single file using the following:

lines = [line.rstrip("\n") for line in open(infile)]

and I'd like to generalize it to multiple input files. I can think of ways to do that with two for loops, but I'd like to know if there is similar 'cute' 'pythonesque' way of doing it in one line. Something along the lines of:

lines = [line.rstrip("\n") for line in open(infile) for infile in infiles]

(which sadly doesn't work...)

Upvotes: 1

Views: 70

Answers (3)

Taha
Taha

Reputation: 778

First, you need to switch the for statements.

lines = [line.rstrip("\n") for line in open(infile) for infile in infiles]

In order to separate different files (to have a list of lists of lines).

liness = [[line.rstrip("\n") for line in open(infile)] for infile in infiles]

The previous step can sometimes be important to separate informations of different files. To obtain lines from liness, you can use:

lines = reduce((lambda a, b: a + b), liness)

Upvotes: 1

A.J. Uppal
A.J. Uppal

Reputation: 19264

Your order is off:

lines = [line.rstrip("\n") for infile in infiles for line in open(infile)]

If you call it your way:

>>> lines = [line.rstrip("\n") for line in open(infile) for infile in infiles]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'infile' is not defined
>>> 

Just as you would use a for loop, use list comprehension:

for infile in infiles:
    for line in open(infile):
        lines.append(line.rstrip("\n"))

Upvotes: 2

Martijn Pieters
Martijn Pieters

Reputation: 1122392

Simply swap the order of your for loops and it'll work:

lines = [line.rstrip("\n") for infile in infiles for line in open(infile)]

List comprehension loops must be listed in the order in which they are nested; if you would nest the loops like:

for infile in infiles:
    for line in open(infile):

then that's also the order in the list comprehension.

Upvotes: 1

Related Questions