Python syntax in Lisp and Scheme

Pascal Costanza costanza at web.de
Tue Oct 7 06:33:52 EDT 2003


David Eppstein wrote:
> In article <blsbpf$i9n$1 at newsreader2.netcologne.de>,
>  Pascal Costanza <costanza at web.de> wrote:
> 
> 
>>I don't know a lot about Python, so here is a question. Is something 
>>along the following lines possible in Python?
>>
>>(with-collectors (collect-pos collect-neg)
>>   (do-file-lines (l some-file-name)
>>     (if (some-property l)
>>       (collect-pos l)
>>       (collect-neg l))))
>>
>>
>>I actually needed something like this in some of my code...
> 
> 
> Not using simple generators afaik.  The easiest way would probably be to 
> append into two lists:
> 
>     collect_pos = []
>     collect_neg = []
>     for l in some_file_name:
>         if some_property(l):
>             collect_pos.append(l)
>         else:
>             collect_neg.append(l)

...but this means that

collect = []
for l in some_file_name
   if some_property:
       collect.append(l)

...is another solution for the single collector case. Now we have two 
ways to do it. Isn't this supposed to be a bad sign in the context of 
Python? I am confused...

> If you needed to do this a lot of times you could encapsulate it into a 
> function of some sort:
> 
> def posneg(filter,iter):
>     results = ([],[])
>     for x in iter:
>         results[not filter(x)].append(x)
>     return results
> 
> collect_pos,collect_neg = posneg(some_property, some_file_name)

What about dealing with an arbitrary number of filters?

(defmacro predicate-collect (list &body predicates)
   (let ((collectors (mapcar (lambda (predicate)
                                (declare (ignore predicate))
                                (gensym "COLLECT"))
                             predicates))
         (collect-t (gensym "COLLECT")))
      `(with-collectors (, at collectors ,collect-t)
          (dolist (l ,list)
            (cond ,@(mapcar (lambda (predicate collector)
                              `((funcall ,predicate l) (,collector l)))
                             predicates collectors)
                  (t (,collect-t l)))))))

An example:

 > (predicate-collect '(-5 -4 -3 -2 -1 0 1 2 3 4 5)
     (function evenp)
     (lambda (n) (< n 0))
     (lambda (n) (> n 3)))
(-4 -2 0 2 4)
(-5 -3 -1)
(5)
(1 3)


I use the list collector macros by Tim Bradshaw here - see 
http://www.tfeb.org/lisp/hax.html#COLLECTING


Pascal

-- 
Pascal Costanza               University of Bonn
mailto:costanza at web.de        Institute of Computer Science III
http://www.pascalcostanza.de  Römerstr. 164, D-53117 Bonn (Germany)





More information about the Python-list mailing list