flattening a dict

Steven D'Aprano steve at REMOVE-THIS-cybersource.com.au
Mon Feb 18 17:22:50 EST 2008


On Mon, 18 Feb 2008 14:03:20 +0000, Duncan Booth wrote:

> Why, why, why, why are you using lambda here? It only makes the code
> harder to read (and it is bad enough without that). A lambda which is
> assigned directly to a variable is a bad code smell.

Oh come on. I don't get this allergy to lambda that so many people have. 
Look at the example given:


def flattendict(d) :
    gen = lambda L : (x for M in exp(L) for x in rec(M))
    exp = lambda L : (L+list(kv) for kv in L.pop().iteritems())
    rec = lambda M : gen(M) if isinstance(M[-1],dict) else [M]
    return dict((tuple(L[:-1]),L[-1]) for L in gen([d]))


The hard-to-read doesn't come from the lambda (which only adds a keyword 
and a name to each function), but the algorithm, which combines 
recursion, generator expressions, and tight coupling between three 
functions. Would the function be any easier to read written like this?

# Untested
def flattendict(d):
    def gen(L):
        return (x for M in exp(L) for x in rec(M))
    def exp(L):
        return (L+list(kv) for kv in L.pop().iteritems())
    def rec(M):
        return gen(M) if isinstance(M[-1],dict) else [M]
    return dict((tuple(L[:-1]),L[-1]) for L in gen([d]))

No. The function is hard to read, not because it uses lambdas, but 
because it is obfuscated Python. The lambda syntax doesn't contribute to 
the obfuscation.

And as for your point about bad code smells, no, I don't agree. If your 
function consists of a single expression, and you don't expect 
func.__name__ to have a meaningful value, then there's nothing wrong with 
using a "named lambda". Anonymous functions are first-class objects in 
Python, just as classes and modules and named functions are, and people 
shouldn't make up superstitious rules about not assigning them to names.

def foo(x):
    return x+1

foo = lambda x: x+1

The first case uses TWO keywords, a name, a declared argument and an 
expression; the lambda form uses ONE keyword, a name, a declared argument 
and an expression. 

The problem with lambdas comes from people trying to hammer multi-
expression functions into a single-expression lambda, hence obfuscating 
the algorithm. That's no different from people who obfuscate multi-
expression functions by writing them as a generator expression.



-- 
Steven



More information about the Python-list mailing list