[Tutor] List comprehension
alan.gauld@bt.com
alan.gauld@bt.com
Sun, 27 Jan 2002 19:45:35 -0000
> As an application I really like defining gcd(a,b) and then
> gathering totatives (positives relatively prime to N and < N)
> by going:
>
> >>> def gcd(a,b):
> while b:
> a,b = b, a%b
> return a
>
> totatives = [t for t in range(1,N) if gcd(t,N)==1]
>
> The lambda form would be:
>
> >>> filter(lambda a: gcd(a,28)==1,range(28))
> [1, 3, 5, 9, 11, 13, 15, 17, 19, 23, 25, 27]
>
> I don't find that any clearer than the list comprehension
> way of doing it.
But let's stop confusing two distinct structures.
The lamda form is a diffrent way of defining a
function object - one with no name.
If you can create a named function(like gcd) then lambda is
not needed, so the "equivalent" form could be:
def gcd(a,b=28):
while b:
a,b = b, a%b
return a == 1
filter(gcd, range(28))
lambda is only used as a quick n dirty way of defining
a short function inine. Its not a necessary part of
the map/filter/reduce syntax.
The Lisp take on Lambdas is that every block of code
is essentially a lambda block and every function is
merely a name referring to a lambda.
This in Lisp there is no difference between declaring
a variable assignment and a function assignment:
(define foo 8)
(define bar (lambda x (+ x x)))
Are completely consistent. Both expressions simply assign
a value (8 and a lambda respectively) to a name
(a variable if you like). That's why Lispers like lambdas
because they bring consistency to the language.
But the FP functions do not rely on lambdas, they rely
on function objects which is a different and more
powerful concept. Thus knowing Lisp makes lambdas readable
but is not the reason I prefer map etc. I simply find:
map(f, Lst)
easier to read than
[f for i in Lst]
Partly coz my brain automatically parses the latter as
(f for i) in Lst
Which makes no sense! Thus I have to consciously back
out and think the construct thru.
Thats why I'd have liked a separator of some sort
between the expression and the for
> >>> reduce(add,[a*b for a in [400,20,3] for b in [300,20,1]])
> 135783
> >>> 423*321
> 135783
Now this is where I think LCs really do start to have
an advantage even if I don't like the syntax.
Alan G