Better structure, caching and generators (counted, not timed)
Python code gets faster mainly by using a better algorithm or data structure, avoiding repeated work with caches, streaming with generators, and moving loops into C through built-ins and NumPy. Only after that do local-variable tricks and native extensions matter.
Change the code and press Run (Ctrl+Enter). Predict what will happen first, then break it on purpose and read what changes. Your edits are saved and match the lesson page.
Ready for more? This phase has 6 hands-on exercises with automatic checks.
Practice questions
Write the code in the editor, run it, then open the model answer to compare.
Make allowed = list(range(2000)). Count how many of the numbers 1999, 5 and 5000 are in allowed, first by testing against the list and then against set(allowed). Print the two counts.
Count the words in "a b a c b a" with a plain dict and .get, and print the dict. Then do it with Counter and print the two most common words.
Write a recursive fib(n) decorated with lru_cache(maxsize=None). Print fib(30), then the number of cache misses and hits from fib.cache_info().
Explain it without notes
Give four general techniques for making Python code faster, in the order you would try them.
Why is x in some_set faster than x in some_list, and when is the list still fine?
Why is NumPy faster than a Python loop for numeric work?
What can go wrong with functools.lru_cache?
Expected output
slow: False in 44850 steps
fast: False in 300 steps
fib(60) = 1548008755920 with 61 real calls
CacheInfo(hits=58, misses=61, maxsize=None, currsize=61)
list is far bigger than generator: True
same answer: True