Home > Dive Into Python > Data-Centric Programming > Filtering lists revisited | << >> | ||||
diveintopython.org Python for experienced programmers |
You're already familiar with using list comprehensions to filter lists. There is another way to accomplish this same thing, which some people feel is more expressive.
Python has a built-in filter function which takes two arguments, a function and a list, and returns a list.[14] The function passed as the first argument to filter must itself take one argument, and the list that filter returns will contain all the elements from the list passed to filter for which the function passed to filter returns true.
Got all that? It's not as difficult as it sounds.
Example 7.7. Introducting filter
>>> def odd(n): ... return n%2 ... >>> li = [1, 2, 3, 5, 9, 10, 256, -3] >>> filter(odd, li) [1, 3, 5, 9, -3] >>> filteredList = [] >>> for n in li: ... if odd(n): ... filteredList.append(n) ... >>> filteredList [1, 3, 5, 9, -3]
Example 7.8. filter in regression.py
files = os.listdir(path) test = re.compile("test.py$", re.IGNORECASE) files = filter(test.search, files)
As we saw in Finding the path, path may contain the full or partial pathname of the directory of the currently running script, or it may contain an empty string if the script is being run from the current directory. Either way, files will end up with the names of the files in the same directory as this script we're running. | |
This is a compiled regular expression. As we saw in Refactoring, if you're going to use the same regular expression over and over, you should compile it for faster performance. The compiled object has a search method which takes a single argument, the string the search. If the regular expression matches the string, the search method returns a Match object containing information about the regular expression match; otherwise it returns None, the Python null value. | |
For each element in the files list, we're going to call the search method of the compiled regular expression object, test. If the regular expression matches, the method will return a Match object, which Python considers to be true, so the element will be included in the list returned by filter. If the regular expression does not match, the search method will return None, which Python considers to be false, so the element will not be included. |
Historical note. Versions of Python prior to 2.0 did not have list comprehensions, so you couldn't filter using list comprehensions; the filter function was the only game in town. Even with the introduction of list comprehensions in 2.0, some people still prefer the old-style filter (and its companion function, map, which we'll see later in this chapter). Both techniques work, and neither is going away, so which one you use is a matter of style.
Example 7.9. Filtering using list comprehensions instead
files = os.listdir(path) test = re.compile("test.py$", re.IGNORECASE) files = [f for f in files if test.search(f)]
Footnotes
[14] Technically, the second argument to filter can be any sequence, including lists, tuples, and custom classes that act like lists by defining the __getitem__ special method. If possible, filter will return the same datatype as you give it, so filtering a list returns a list, but filtering a tuple returns a tuple.
Finding the path | 1 2 3 4 5 6 | Mapping lists revisited |