lazy evaluation and late binding of python?

2.4k Views Asked by At

when is lazy evaluation? (generator, if, iterator?), when is late binding? (closure, regular functions?)

    a = [1,2,3,4]
    b = [lambda y: x for x in a] 
    c = (lambda y: x for x in a) #lazy evaluation
    d = map(lambda m: lambda y:m, a) #closure
    for i in b:
        print i(None)
    # 4 4 4 4
    for i in c:
        print i(None)
    # 1 2 3 4 
    for i in d:
        print i(None)
    # 1 2 3 4
1

There are 1 best solutions below

7
On BEST ANSWER

This looks like homework, so I won't just give you the answers. Here are two functions that you can step through and see how the values change.

def make_constants_like_generator():
    def make_constant(x):
        def inner(y):
            return x
        return inner
    results = []
    for i in [1, 2, 3, 4]:
        results.append(make_constant(i))
        for f in results:
            print f(None)
    return results

def make_constants_like_list():
    x = None
    results = []
    for i in [1, 2, 3, 4]:
        x = i
        def inner(y)
            return x
        results.append(inner)
        for f in results:
            print f(None)
    return results

Lazy evaluation is waiting until the last possible moment to evaluate an expression. The opposite is eager evaluation. The generator expression is lazy, it does nothing until it is iterated. The list expression is eager, as soon as it is encountered, the list is filled with values.

Early and late binding relate to how the system determines what a name refers to. All names in python are late bound. Combined with lazy evaluation that means that what a name is bound to can change before expressions that use it are evaluated

def map(func, iter):
    return (func(val) for val in iter)