loops -> list/generator comprehensions

Steven Bethard steven.bethard at gmail.com
Sun Feb 6 16:53:48 EST 2005


Caleb Hattingh wrote:
>> filenames = [os.path.join(dirpath, filename)
>               # This is cool
>               for dirpath, _, filenames in os.walk('.')
>               # This is getting tricky, whats the '_' for?

Nothing to do with the list comprehension really.  '_' is a commonly 
used variable name for an object that we don't care about.  If you look 
at the OP's original code, the line:

    [(x[0], x[2]) for x in os.walk(".")]

is the equivalent of:

    [dirpath, filenames for dirpath, dirnames, filenames in os.walk('.')]

I prefer to give names to the values produced by os.walk -- I think it 
makes the usage much clearer.  However, since I don't use 'dirnames', I 
use '_' to indicate this:

    [dirpath, filenames for dirpath, _, filenames in os.walk('.')]

Would

     filenames = [os.path.join(dirpath, filename)
                  for dirpath, dirnames, filenames in os.walk('.')
                  for filename in filenames]

have been clearer for you?  Then all you have to do is remember the 
order of the for-loop execution:

>               # Which thing  goes where again in a comprehension?
>               for filename in filenames]

As mentioned in my other post, the order is identical to that of 
for-loops, e.g.

     result = []
     for dirpath, _, filenames in os.walk('.'):
         for filename in filenames:
             result.append(os.path.join(dirpath, filename))

is basically equivalent to:

     [os.path.join(dirpath, filename)
      for dirpath, _, filenames in os.walk('.')
      for filename in filenames]

Does that help?

Steve



More information about the Python-list mailing list