Alan Dong
Alan Dong

Reputation: 4095

Python list comprehension with lambda

Can someone please explain to me

  1. Why a is a list of True/False, while b is a list of lambdas?

  2. Why does the rule does not apply to c and d?

Codes:

foo = (lambda a, b: a >= b) if False else (lambda a, b: a <= b)
a = [foo(x, x+1) for x in xrange(10)]

foo = lambda a, b: a >= b if False else lambda a, b: a <= b
b = [foo(x, x+1) for x in xrange(10)]

bar = (lambda a, b: a*b*10) if False else (lambda a, b: a*b*100)
c = [bar(x, x+1) for x in xrange(10)]

bar = lambda a, b: a*b*10 if False else lambda a, b: a*b*100
d = [bar(x, x+1) for x in xrange(10)]

Thank you in advance.

Upvotes: 1

Views: 179

Answers (2)

BlackBear
BlackBear

Reputation: 22979

It is just a matter of operator precedence. Let's put some brackets to show how the statements are parsed:

(a) foo = (lambda a, b: a >= b) if True else (lambda a, b: a <= b)
(b) foo = lambda a, b: (a >= b if descending else lambda a, b: a <= b)

When evaluating (b) descending happens to be false, so all the elements become lambda a, b: a <= b

Upvotes: 4

Joran Beasley
Joran Beasley

Reputation: 113930

foo = lambda a, b: a >= b if descending else lambda a, b: a <= b
b = [foo(x, x+1) for x in xrange(10)]

can be rewritten as

foo = lambda a, b:  (a >= b if descending else lambda a, b: a <= b)
b = [foo(x, x+1) for x in xrange(10)]

which if it is descending is fine as LHS is evaluated to

foo = lambda a,b: a >= b  #does what you would expet

but if its not you get

foo = lambda a,b: lambda a,b:a<=b

which clearly returns a lambda not a value

you could change it to

foo = lambda a, b: a >= b if descending else  a <= b
b = [foo(x, x+1) for x in xrange(10)]

and it should work as you expect

Upvotes: 1

Related Questions