Python Optimisation Patterns
An optimisation pattern changes the shape of code and keeps the same output. str.join builds one string from many pieces.
Join pieces at once
join takes a list of strings. It glues them with the text you give.
words = ["red", "green", "blue"]
print("-".join(words))Save a method in a local name
The dot lookup happens once here. The loop then uses the plain name add.
result = []
add = result.append
for word in ["cat", "dog", "bird"]:
add(word.upper())
print(result)Test membership in a set
The word in works on a set too. The answer comes from a fast lookup.
allowed = {"ana", "bo", "cy"}
print("bo" in allowed)
print("dee" in allowed)Fix attributes with slots
This class may only use x and y. No other attribute names are allowed.
class Point:
__slots__ = ("x", "y")
print(Point.__slots__)Example
def count_naive(words):
counts = {}
seen = []
for word in words:
if word not in seen:
seen.append(word)
counts[word] = words.count(word)
return counts
def count_fast(words):
counts = {}
seen = set()
for word in words:
if word not in seen:
seen.add(word)
counts[word] = words.count(word)
return counts
words = "the cat sat on the mat the cat".split()
print(count_naive(words))
print(count_fast(words))
print(count_naive(words) == count_fast(words))Key points
- Use str.join to build one string from many pieces.
- Adding text with += in a loop can build a new string each step.
- Local lookup: a local name is found faster than a dotted name.
- Use a set or a dict to test membership.
- A list must scan item by item.
- Slots: __slots__ fixes the attribute names a class may use.
- It can save memory and block new attributes.
- Rule: readable first, fast second.
- Change code only after you measure it.
- An optimisation pattern changes how code is shaped and keeps its output the same.
In this example, both functions count the same words. The naive one keeps seen words in a list. Each membership test scans that list. The fast one keeps seen words in a set. Its membership test uses the fast set lookup. Both return the same dict, and the last line proves it. Only the shape changed, not the answer.
Note
A set finds members with a fast lookup trick.
A list has no such shortcut.
Try it Yourself
Edit the code, then press Run.
Running is simulated · Python Playground
Exercise
You must build one long string from many pieces in a loop. Which tool fits best?