Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

lazy evaluation and late binding of python?

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
like image 875
QuantumEnergy Avatar asked Oct 18 '22 06:10

QuantumEnergy


1 Answers

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)
like image 157
Caleth Avatar answered Oct 20 '22 20:10

Caleth