[Newby question] List comprehension

Discussion in 'Python' started by Eelco Hoekema, Aug 6, 2004.

  1. I'm trying to get a list of tuples, with each tuple consisting of a
    directory, and a list of files. I only want a tuple if and only if the
    filtered list of files is not empty. And, i want the list of files in the
    tuples to be filtered. For this, i came up with the following code:

    <code>

    # song filter: will return true if the file seems to be an mp3 file.
    # (may not be the best way to do this)
    def song(f):
    (name, ext) = os.path.splitext(f)
    return ext.lower() == '.mp3'

    # list comprehension walking through a directory tree
    [(root, filter(song, files)) for (root, dir, files) in os.walk(os.path.abspath('.')) if filter(song, files)]


    </code>

    Now, this will work. However, it seems kind of silly to call the filter
    twice. Is there a way to keep this in one list comprehension, but with
    just filtering once?

    eelco
     
    Eelco Hoekema, Aug 6, 2004
    #1
    1. Advertising

  2. Eelco Hoekema

    Tom B. Guest

    "Eelco Hoekema" <> wrote in message
    news:p...
    >
    > I'm trying to get a list of tuples, with each tuple consisting of a
    > directory, and a list of files. I only want a tuple if and only if the
    > filtered list of files is not empty. And, i want the list of files in the
    > tuples to be filtered. For this, i came up with the following code:
    >
    > <code>
    >
    > # song filter: will return true if the file seems to be an mp3 file.
    > # (may not be the best way to do this)
    > def song(f):
    > (name, ext) = os.path.splitext(f)
    > return ext.lower() == '.mp3'
    >
    > # list comprehension walking through a directory tree
    > [(root, filter(song, files)) for (root, dir, files) in

    os.walk(os.path.abspath('.')) if filter(song, files)]
    >
    >
    > </code>
    >
    > Now, this will work. However, it seems kind of silly to call the filter
    > twice. Is there a way to keep this in one list comprehension, but with
    > just filtering once?
    >
    > eelco
    >
    >

    How about,

    fltres = filter(song, files)
    [(root, fltres ) for (root, dir, files) in os.walk(os.path.abspath('.')) if
    fltres]

    Tom
     
    Tom B., Aug 6, 2004
    #2
    1. Advertising

  3. Eelco Hoekema

    Larry Bates Guest

    Actually I think (??) this is better done in a loop:
    (not tested)

    toc=[]
    for root, dir, files in os.walk(os.path.abspath('.')):
    mp3files=[f for f in files if f.lower().endswith('.mp3')]
    if mp3files: toc.append((root, mp3files))


    HTH,
    Larry Bates
    Syscon, Inc.

    "Eelco Hoekema" <> wrote in message
    news:p...
    >
    > I'm trying to get a list of tuples, with each tuple consisting of a
    > directory, and a list of files. I only want a tuple if and only if the
    > filtered list of files is not empty. And, i want the list of files in the
    > tuples to be filtered. For this, i came up with the following code:
    >
    > <code>
    >
    > # song filter: will return true if the file seems to be an mp3 file.
    > # (may not be the best way to do this)
    > def song(f):
    > (name, ext) = os.path.splitext(f)
    > return ext.lower() == '.mp3'
    >
    > # list comprehension walking through a directory tree
    > [(root, filter(song, files)) for (root, dir, files) in

    os.walk(os.path.abspath('.')) if filter(song, files)]
    >
    >
    > </code>
    >
    > Now, this will work. However, it seems kind of silly to call the filter
    > twice. Is there a way to keep this in one list comprehension, but with
    > just filtering once?
    >
    > eelco
    >
    >
     
    Larry Bates, Aug 6, 2004
    #3
  4. Larry Bates schreef:

    > Actually I think (??) this is better done in a loop:
    > (not tested)
    >
    > toc=[]
    > for root, dir, files in os.walk(os.path.abspath('.')):
    > mp3files=[f for f in files if f.lower().endswith('.mp3')]
    > if mp3files: toc.append((root, mp3files))


    That is about the same as Facundo Bastida said. But then, i like this
    better:

    tmp = [(root, files) for (root, dir, files) in os.walk(os.path.abspath('.')) if files]
    toc = [(root, files) for (root, files) tmp if filter(song, files)]

    But that means 2 list comprehensions. Ans i'm just wondering if it can be
    done in one, without filtering twice.

    eelco
     
    Eelco Hoekema, Aug 6, 2004
    #4
  5. On Fri, 6 Aug 2004, Eelco Hoekema wrote:

    > [(root, filter(song, files)) for (root, dir, files) in
    > os.walk(os.path.abspath('.')) if filter(song, files)]
    >
    > Now, this will work. However, it seems kind of silly to call the filter
    > twice. Is there a way to keep this in one list comprehension, but with
    > just filtering once?


    You may do best to split this into two LCs:

    temp = [(root, filter(song,files)) for (root, dir, files) in
    os.walk(os.path.abspath('.'))]
    temp = [(root, songs) for (root, songs) in temp if songs]

    Or if you prefer, replace the latter with:
    temp = filter(temp, lambda x: x[1])

    Or even, in 2.4:
    temp = filter(temp, itemgetter(1))

    In 2.4, you will also be able to replace the first LC with a generator
    expression, saving a bit of both memory and processor time (the change
    would consist of replacing the brackets with parentheses).

    Hope this helps.
     
    Christopher T King, Aug 6, 2004
    #5
  6. Eelco Hoekema schreef:

    > That is about the same as Facundo Bastida said. But then, i like this
    > better:


    > tmp = [(root, files) for (root, dir, files) in os.walk(os.path.abspath('.')) if files]
    > toc = [(root, files) for (root, files) tmp if filter(song, files)]


    Hmm. That doesn't work. It's the other way around, like Christoffer
    King showed:

    tmp = [(root, files) for (root, dir, files) in os.walk(os.path.abspath('.')) if filter(song, files)]
    toc = [(root, files) for (root, files) tmp if files]

    eelco
     
    Eelco Hoekema, Aug 6, 2004
    #6
  7. Eelco> # song filter: will return true if the file seems to be an mp3 file.
    Eelco> # (may not be the best way to do this)
    Eelco> def song(f):
    Eelco> (name, ext) = os.path.splitext(f)
    Eelco> return ext.lower() == '.mp3'

    Eelco> # list comprehension walking through a directory tree
    Eelco> [(root, filter(song, files)) for (root, dir, files) in os.walk(os.path.abspath('.')) if filter(song, files)]

    In this particular case, since song() only returns True or False, you could
    use

    [(root, True) for (root, dir, files) in os.walk(os.path.abspath('.'))
    if filter(song, files)]

    Skip
     
    Skip Montanaro, Aug 6, 2004
    #7
  8. Skip Montanaro schreef:

    > Eelco> # list comprehension walking through a directory tree
    > Eelco> [(root, filter(song, files)) for (root, dir, files) in os.walk(os.path.abspath('.')) if filter(song, files)]


    > In this particular case, since song() only returns True or False,


    song() does return True or False, but the return value is used in the
    filter, which returns a list.

    > you could use


    > [(root, True) for (root, dir, files) in os.walk(os.path.abspath('.'))
    > if filter(song, files)]


    That would yield a list of tuples of directories that contain at least one
    song. Could still be of use.

    eelco
     
    Eelco Hoekema, Aug 6, 2004
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Batista, Facundo

    RE: [Newby question] List comprehension

    Batista, Facundo, Aug 6, 2004, in forum: Python
    Replies:
    8
    Views:
    301
    Peter Hansen
    Aug 6, 2004
  2. Shane Geiger
    Replies:
    4
    Views:
    396
    bullockbefriending bard
    Mar 25, 2007
  3. Debajit Adhikary
    Replies:
    17
    Views:
    699
    Debajit Adhikary
    Oct 18, 2007
  4. Vedran Furac(
    Replies:
    4
    Views:
    339
    Marc 'BlackJack' Rintsch
    Dec 19, 2008
  5. GMAN1941

    List question from newby

    GMAN1941, Jul 25, 2013, in forum: Python
    Replies:
    0
    Views:
    144
    GMAN1941
    Jul 25, 2013
Loading...

Share This Page