Lazy evaluation is a code optimization strategy in which repetitive evaluations are omitted by evaluating expressions only when they are required. This strategy can be helpful when we need to compute a time-consuming expression needed only a few times. It’s counter part is strict evaluation, which involves immediate evaluation of Pythonic expressions. Although being lazy is considered bad in the real world but in programming it can actually be fruitful and sometimes even more efficient by saving precious resources. We have been using lazy evaluation functions for the longest time without being aware of it. In this Answer, we’ll go through some of these functions and dive deep into the benefits and limitations of lazy evaluation.
Let’s review some of the functions commonly used to implement lazy evaluation in Python.
range()
The range()
method is a more efficient way of traversing Python lists, saving both memory and time. In the code given below, we create two ranges. The first my_range_1
returns a list of six elements, while the second returns 666
items. However, despite the great difference between the number of list items returned, the size of the range object returned is the same for both ranges. This is because range()
does not immediately create a list of items in memory. Instead, it only stores the starting, step, and stopping values in memory while each item in the range is computed when required.
import sysmy_range_1 = range(6)my_range_2 = range(666)print(sys.getsizeof(my_range_1))print(sys.getsizeof(my_range_2))
zip()
The zip()
function returns a tuple created by merging two iterables. This method is an example of a
my_list_1 = [1, 2, 3, 4]my_list_2 = ['a', 'b', 'c', 'd']zipped = zip(my_list_1, my_list_2) # Use zip() to merge the two lists into tupleszipped_list = list(zipped) # Convert the zipped object to a list of tuplesprint(zipped_list)
open()
The open()
method is another generator method that returns an iterable file object. Instead of reading the entire file at once, it only reads the file parts that are requested while iterating via the generator.
with open("my_file.txt", "r") as file_reader:for one_line in file_reader:print(one_line)
lambda
and map
functionsA lambda
function is another way to implement lazy evaluation in Python. This anonymous function does not take up space in memory. Moreover, we further optimize our code by using the map
function. It will call the lambda
function for all items in an iterable like a list.
my_map_object = map(lambda x : x*x + 2, [1,10,5])print(my_map_object)
The following section shows the ups and downs of using lazy evaluation in our Python code.
Benefits | Limitations |
Increased code performance | Debugging errors may become difficult |
Time and memory optimization | Memory leaks |
Flexibility in evaluating large-scale processing tasks | In non-functional languages, implementing lazy evaluation may be complex |
To wrap things up, sometimes being lazy might be the quickest and most efficient way to get something done. This is true for both real life and for the Python programming paradigm. With lazy evaluation functions like range()
, map()
and zip()
etc., we can efficiently manage both memory allocation and execution time.
Free Resources