🎓 A1Learner
🔍

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?