Yield and generators
import time
start = time.time()
def even_numbers(n):
for i in range(0, n+1, 2):
yield i
numbers = even_numbers(10_000_000)
evens = []
for number in numbers:
evens.append(number)
end = time.time()
print(end-start)
start2 = time.time()
evens2 =[]
for n in range(10_000_000):
if n%2 ==0:
evens2.append(n)
end2 = time.time()
print(end2-start2)
# 0.8700542449951172
# 1.6380994319915771
Efficiency Analysis
- Generator Function (Method 1): This method is more efficient, taking about 0.87 seconds to complete.
- Direct Loop (Method 2): This method is less efficient, taking about 1.64 seconds to complete.
Reasons for Efficiency Difference
Iteration Range:
- Method 1 iterates only over even numbers (0, 2, 4, …, 10,000,000).
- Method 2 iterates over all numbers from 0 to 9,999,999. Condition Checking:
- Method 1 doesn’t need to check if a number is even; it generates only even numbers.
- Method 2 checks every number with the condition n//2 ==0, which is actually incorrect (should be n % 2 == 0). Memory Usage:
- Method 1 uses a generator, which yields values one at a time, saving memory.
- Method 2 creates the entire range in memory before iterating.
Number of Operations:
- Method 1 performs fewer operations overall, as it only deals with even numbers.
- Method 2 performs more operations, checking every number and doing an integer division for each.
Most efficient method
start3 = time.time()
evens3 = list(range(0, 10_000_000, 2))
end3 = time.time()
print(end3-start3)
# 0.2165060043334961
Tags:
Python, Yield, Generators, Data_structures_in_action