Writing better loops
1. Writing better loops
We've discussed how loops can be costly and inefficient. But, sometimes you can't eliminate a loop. In this lesson, we'll explore how to make loops more efficient when looping is unavoidable.2. Lesson caveat
Before diving in, some of the loops we'll discuss can be eliminated using techniques covered in previous lessons. For demonstrative purposes, we'll assume the use cases shown here are instances where a loop is unavoidable.3. Writing better loops
The best way to make a loop more efficient is to analyze what's being done within the loop. We want to make sure that we aren't doing unnecessary work in each iteration. If a calculation is performed for each iteration of a loop, but its value doesn't change with each iteration, it's best to move this calculation outside (or above) the loop. If a loop is converting data types with each iteration, it's possible that this conversion can be done outside (or below) the loop using a map function. Anything that can be done once should be moved outside of a loop. Let's explore a few examples.4. Moving calculations above a loop
We have a list of Pokémon names and an array of each Pokémon's corresponding attack value. We'd like to print the names of each Pokémon with an attack value greater than the average of all attack values. To do this, we'll use a loop that iterates over each Pokémon and their attack value. For each iteration, the total attack average is calculated by finding the mean value of all attacks. Then, each Pokémon's attack value is evaluated to see if it exceeds the total average. Can you spot the inefficiency? The total_attack_avg variable is being created with each iteration of the loop. But, this calculation doesn't change between iterations since it is an overall average. We only need to calculate this value once.5. Moving calculations above a loop
By moving this calculation outside (or above) the loop, we calculate the total attack average only once. We get the same output, but this is a more efficient approach.6. Moving calculations above a loop
Comparing runtimes, we see that keeping the total_attack_avg calculation within the loop takes roughly 75 microseconds.7. Moving calculations above a loop
Moving the calculation takes about half the time.8. Using holistic conversions
Another way to make loops more efficient is to use holistic conversions outside (or below) the loop. We have three lists from our dataset of 720 Pokémon: a list of each Pokémon's name, a list corresponding to whether or not a Pokémon has a legendary status, and a list of each Pokémon's generation. We want to combine these objects so that each name, status, and generation is stored in an individual list. To do this, we'll use a loop that iterates over the output of the zip function. Remember, zip returns a collection of tuples, so we need to convert each tuple into a list since we want to create a list of lists as our output. Now, we append each individual poke_list to our poke_data output variable. By printing the result, we see our desired list of lists. However, converting each tuple to a list within the loop is not very efficient.9. Using holistic conversions
Instead, we should collect all of our poke_tuples together, and use the map function to convert each tuple to a list. The loop no longer converts tuples to lists with each iteration. Instead, we moved this tuple to list conversion outside (or below) the loop. That way, we convert data types all at once (or holistically) rather than converting in each iteration.10. Using holistic conversions
Runtimes show that converting each tuple to a list outside of the loop is more efficient.11. Time for some practice!
Let's practice writing more efficient loops!Create Your Free Account
or
By continuing, you accept our Terms of Use, our Privacy Policy and that your data is stored in the USA.