views:

551

answers:

6

Is it possible to append elements to a python generator?

I'm currently trying to get all images from a set of disorganized folders and write them to a new directory. To get the files, I'm using os.walk() which returns a list of image files in a single directory. While I can make a generator out of this single list, I don't know how to combine all these lists into one single generator. Any help would be much appreciated.

Related:

+3  A: 
def files_gen(topdir='.'):
    for root, dirs, files in os.walk(topdir):
        # ... do some stuff with files
        for f in files:
            yield os.path.join(root, f)
        # ... do other stuff

for f in files_gen():
    print f
J.F. Sebastian
A: 

Like this.

def threeGens( i, j, k ):
    for x in range(i):
       yield x
    for x in range(j):
       yield x
    for x in range(k):
       yield x

Works well.

S.Lott
`itertools.chain(range(i), range(j), range(k))`
J.F. Sebastian
@J.F. Sebastian: Not when the range is os.walk(...).
S.Lott
+1  A: 

Just yeld each of generated element individually, not as list.

UPDATE: I've just discovered itertools.chain() that should be effective and elegant solution.

myroslav
+6  A: 

You are looking for itertools.chain. It will combine multiple iterables into a single one, like this:

>>> for i in itertools.chain([1,2,3], [4,5,6]):
...  print i
... 
1
2
3
4
5
6
dF
How do you use `chain` in the context of `os.walk`?
J.F. Sebastian
+10  A: 

This should do it, where directories is your list of directories:

import os
import itertools

generators = [os.walk(d) for d in directories]
for root, dirs, files in itertools.chain(*generators):
    print root, dirs, files
Ryan Bright
`chain.from_iterable(imap(os.walk, directories))`
J.F. Sebastian
A: 

hey, thanks, this is was I was looking for too:

I had this code snippet...

grids = []
for item in input_files:
  grids.extend([... some list comprehension ...])

and wanted to rewrite it using generators... my first guess (and hope) was this:

grids = generator()
for item in input_files:
  grids.extend((... some list comprehension ...))

but there's no such constructor nor method. using itertools I have this:

grids = itertools.chain()
for item in input_files:
  grids = itertools.chain(grids, (... some list comprehension ...))

which seems good enough to me.
thanks to stackoverflow and their users!

mariotomo