1

like this question I want to pass a function with arguments. But I want to pass it to built-in functions.

Example:

files = [ 'hey.txt', 'hello.txt', 'goodbye.jpg', 'howdy.gif' ]

def filterex(path, ex):
  pat = r'.+\.(' + ex + ')$'
  match = re.search(pat, path)         
  return match and match.group(1) == ex) 

I could use that code with a for loop and an if statement but it's shorter and maybe more readable to use filter(func, seq). But if I understand correctly the function you use with filter only takes one argument which is the item from the sequence.

So I was wondering if it's possible to pass more arguments?

Community
  • 1
  • 1
Pickels
  • 33,902
  • 26
  • 118
  • 178

2 Answers2

8
def make_filter(ex):
    def do_filter(path):
        pat = r'.+\.(' + ex + ')$'
        match = re.search(pat, path)
        return match and match.group(1) == ex
    return do_filter

filter(make_filter('txt'), files)

Or if you don't want to modify filterex:

filter(lambda path: filterex(path, 'txt'), files)

You could use a list comprehension, as suggested by gnibbler:

[path for path in files if filterex(path, 'txt')]

You could also use a generator comprehension, which might be particularly useful if you had a large list:

(path for path in files if filterex(path, 'txt'))
Matthew Flaschen
  • 278,309
  • 50
  • 514
  • 539
3

Here is a list comprehension that does the same thing

import os
[f for f in files if os.path.splitext(f)[1]=="."+ex]
John La Rooy
  • 295,403
  • 53
  • 369
  • 502
  • Thanks I a lot gnibbler. I have list comprehensions in other parts of my code but it seems I didn't make the connection to my filter function. I'll use the 'I am new excuse'. – Pickels Jul 04 '10 at 01:20