Iterating through two lists

holger krekel pyth at devel.trillke.net
Fri May 24 08:47:17 EDT 2002


jb wrote:
> holger krekel wrote:
> 
> > no doubt, you get hundreds of suggestions. pythoneers *love*
> > these kind of tasks :-)
> > 
> >     for (a,b) in zip(x,y): a.f(b)
> > 
> > would be the most straigtforward, i guess.
> 
> Thx. Have you read by any chance Paul Graham's article at 
> http://www.paulgraham.com/icad.html ? He makes a few remarks as to how 
> Python is not (yet) sufficient, if I understod correctly. I should be 
> intrested in a Python expert's opinion on this.

thanks for the pointer. it's very well worth reading.

But my take on using python's power would be  different than
in the article. For joining readers of this thread:
--

In his article 'Revenge of the nerds' Paul Graham discusses 
different solutions for this problem:

  "We want to write a function that generates accumulators--
   a function that takes a number n, and returns a function 
   that takes another number i and returns n incremented by i.
   (That's incremented by, not plus. An accumulator has to accumulate.)"

he goes on by giving the lisp example and a perl example:

(defun foo (n)
  #'(lambda (i) (incf n i)))
 and in Perl 5, 

sub foo {  
  my ($n) = @_;
  sub {$n += shift}
}

And intensively discusses the python version which is wordier
and does indeed look somewhat hackish/longish.

-- 

Now what i appreciate about python is that you can
implement *generic* patterns as needed. So my
little implementation makes the solution just a 'special case':

class accumulator:
    def __init__(self, obj, method='__add__'):
        self.obj=obj
        self.method=method

    def __call__(self, *args):
        if type(self.method) is str:
            result = getattr(self.obj, self.method) (*args)
        else:
            result = self.method(self.obj, *args)

        if type(result) == type(self.obj):
            self.obj=result 

        return self.obj 


this allows to do the following:

>>> inc = accumulator(5)
>>> print inc(3)
8
>>> print inc(5)
13

you can give complex numbers or strings to accumulator as well
(as long as the later passed arguments are consistent, that is!).

But you can do even more, e.g.:

>>> linc2=accumulator([], list.append)
>>> print linc2(3)
[3]
>>> print linc2('hallo')
[3, 'hallo']
>>> print linc2(3+5j)
[3, 'hallo', (3+5j)]
>>>

So my argument is: python might be a bit more wordy for very
simple requirements. but it doesn't require much more effort 
if you handle more generic cases. In *this* respect python 
probably isn't much behind lisp or perl. 

I'd *guess* it's even ahead in lots of cases :-)

    holger





More information about the Python-list mailing list