List Comprehensions vs. filter-map
I've been doing some Python scripting
this week, and discovered that you can put
if filters on list
comprehensions. I love list comprehensions to begin with and this makes them
even cooler. For example, to filter only numbers out of a list, I defined
isNumberish based on recipe 3.2 in the Python Cookbook, and then
wrote a filter like this: def isNumberish(anobj): ... try: anobj + 0 ... except: return 0 ... else: return 1 [x * x for x in ['a', 1, 'b', 3, 'c', 7] if isNumberish(x)] [1, 9, 49]In Scheme, SRFI-1 provides
filter-map to do effectively the
same thing. It's a bit less clear what goes on here; filter-map
accumulates only true values (it might be more to the point to say anything not
#f). (require (lib "1.ss" "srfi"))
(filter-map (lambda (x) (and (number? x) (* x x))) '("a" 1 "b" 3 "c" 7))
(1 9 49)
filter-map could get you in a bit of trouble if you wanted to
work with booleans: (filter-map (lambda (x) (and (boolean? x) (not x))) '("a" 1 "b" #t "c" #f))
(#t)
(map not (filter boolean? '("a" 1 "b" #t "c" #f)))
(#f #t)
Python can handle this OK, though: [not x for x in ['a', 1, 'b', True, 'c', False] if type(x) == type(True)] [False, True]