Vectorising with NumPy
np.vectorize still calls your Python function for every element. np.square is a real ufunc and calls no Python code per element.
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
loop result: 332833500
numpy result: 332833500
same: True
Python function calls for map: 1000
np.vectorize still calls Python: True
a real ufunc calls it 0 times: True