
On Mon, 22 Jun 2009 08:40:05 pm Nick Coghlan wrote:
Lambdas, comprehensions and expressions in general all have limits - usually deliberate ones. When one runs up against those limits it is a hint that it is time to switch to using multiple statements (typically factored out into a function that can be substituted for the original inline expression)
+1
But then, I'll freely confess to not really understanding the apparently common obsession with wanting to be able to do everything as an expression.
Some things are conceptually a single operation, and those things are good to write as a single expression. Before we had sorted(), it was uncomfortable to write: L.sort() return L when you wanted a sorted list, because "return a sorted list" is conceptually a single operation, even if sorting is non-trivial. The solution to this was to write a helper function, which was made obsolete when sorted() became a built-in. The OP's suggestion: [(f(x), f(x)) for x in some_iterable if f(x) < 2] is not conceptually a single operation, because producing a list of two-tuples containing some value y repeated but only if y is less than 2 is not conceptually simple. If it were, it would be easy to describe the operation with one or two words, instead of the fourteen it took me. I still believe that the right way to solve this is with a pipeline of simple operations: map(lambda obj: (obj, obj), filter(lambda y: y < 2, map(f, some_iterable))) Re-write with temporary variables, itertools, and generator expressions as preferred. -- Steven D'Aprano