Reputation: 8314
I have a list of open (for reading) file handles. I would like to iterate over every line of every file using a single loop, rather than creating an outer loop to iterate over the list of file handles and a nested inner loop to iterate over the lines. It looks like itertools.chain()
is designed for precisely this purpose, but I cannot get it to work. What am I doing wrong?
Here is a simple example to illustrate.
$ python
Python 2.7.10 (default, May 26 2015, 13:08:10)
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.57)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> fh1 = open('file1', 'r')
>>> fh2 = open('file2', 'r')
>>> import itertools
>>> input = itertools.chain([fh1, fh2])
>>> for line in input:
... print line
...
<open file 'file1', mode 'r' at 0x10c2a6780>
<open file 'file2', mode 'r' at 0x10c2a64b0>
Upvotes: 3
Views: 479
Reputation: 361927
Don't wrap the arguments in a list. Pass them directly.
input = itertools.chain(fh1, fh2)
If you already have a list you can use one of these:
files = [...]
input = itertools.chain(*files)
input = itertools.chain.from_iterable(files)
Upvotes: 4
Reputation: 107347
The itertools.chain
will chain the iterable objects that you have passed to it and in this case you just passed one list ([fh1, fh2]
) so it will just return an iterator contain that list.
If you want to chain your file objects you need to pass them outside the list or unpack the list :
input = itertools.chain(fh1, fh2)
Or:
input = itertools.chain(*[fh1, fh2])
Demo :
>>> list(chain(range(5),range(2),range(3)))
[0, 1, 2, 3, 4, 0, 1, 0, 1, 2]
Upvotes: 3