The first part of code creates a list of lambdas which each take single argument x and multiplies it with i. Note that each lambda is bound to variable i not its' current value. Since the value of i after the list comprehension is 4 each lambda will return x * 4:
>>> def create_multipliers():
... return [lambda x: i * x for i in range(5)]
...
>>> l = create_multipliers()
>>> l[0](1)
4
>>> l[4](1)
4
>>> l[4]('foobar')
'foobarfoobarfoobarfoobar'
The loop will then execute each lambda with parameter 2 and print the results to same line. Since there are 5 lambdas and 4 * 2 is 8 you get the output that you see. , after the print statement will result the output to be printed on the same line:
>>> for multiplier in l:
... print multiplier(2),
...
8 8 8 8 8
make_incrementor works with same principle. It returns a lambda that takes single argument x which is "decided" when lambda is called. It will then return x + n where n is the value passed to make_incrementor:
>>> def make_incrementor(n):
... return lambda x: x + n
...
>>> inc = make_incrementor(2) # n is "decided" here
>>> inc(3) # and x here
5
UPDATE Example with nested functions:
>>> def make_incrementor(n):
... def nested(x):
... return x + n
... return nested
...
>>> inc = make_incrementor(2)
>>> inc(3)
5