What is lazy evaluation in Python?
One website said :
In Python 3.x the range()
function returns a special range object which computes elements of the list on demand (lazy or deferred evaluation):
>>> r = range(10) >>> print(r) range(0, 10) >>> print(r[3]) 3
What is meant by this?
Lazy evaluation is an evaluation strategy which holds the evaluation of an expression until its value is needed. It avoids repeated evaluation. Haskell is a good example of such a functional programming language whose fundamentals are based on Lazy Evaluation.
Yes, Python evaluates boolean conditions lazily. The docs say, The expression x and y first evaluates x; if x is false, its value is returned; otherwise, y is evaluated and the resulting value is returned.
It is a property decorator that gets out of the way after the first call. It allows you to auto-cache a computed value. The standard library @property decorator is a data descriptor object and is always called, even if there is an attribute on the instance of the same name.
Solution 2: Use the '__getattr__' Special Method In Python, functions that have double underscores before and after their names are called special or magic methods. Some people also call them dunder (i.e., double underscores) methods. One particular special method — __getattr__ — can help us implement lazy attributes.
The object returned by range()
(or xrange()
in Python2.x) is known as a lazy iterable.
Instead of storing the entire range, [0,1,2,..,9]
, in memory, the generator stores a definition for (i=0; i<10; i+=1)
and computes the next value only when needed (AKA lazy-evaluation).
Essentially, a generator allows you to return a list like structure, but here are some differences:
A generator can be created in two ways:
(1) Very similar to a list comprehension:
# this is a list, create all 5000000 x/2 values immediately, uses [] lis = [x/2 for x in range(5000000)] # this is a generator, creates each x/2 value only when it is needed, uses () gen = (x/2 for x in range(5000000))
(2) As a function, using yield
to return the next value:
# this is also a generator, it will run until a yield occurs, and return that result. # on the next call it picks up where it left off and continues until a yield occurs... def divby2(n): num = 0 while num < n: yield num/2 num += 1 # same as (x/2 for x in range(5000000)) print divby2(5000000)
Note: Even though range(5000000)
is a generator in Python3.x, [x/2 for x in range(5000000)]
is still a list. range(...)
does it's job and generates x
one at a time, but the entire list of x/2
values will be computed when this list is create.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With