🎓 A1Learner
🔍

Python deque, namedtuple & ChainMap

deque, namedtuple, and ChainMap are three extra structures in collections.

A real queue with deque

A list makes pop(0) move every other item. A deque takes from the left end fast.

from collections import deque

queue = deque(["first", "second"])
queue.append("third")
print(queue.popleft())
print(list(queue))

Work at both ends

appendleft adds at the front. pop and popleft take from opposite ends.

queue = deque([1, 2, 3])
queue.appendleft(0)
print(list(queue))
print(queue.pop(), queue.popleft())

Quick records with namedtuple

A namedtuple gives tuple fields readable names. You saw typing.NamedTuple earlier. It is the typed sibling of this older form.

from collections import namedtuple

Point = namedtuple("Point", ["x", "y"])
p = Point(3, 4)
print(p)
print(p.x, p.y)

Layer dicts with ChainMap

ChainMap searches the first dict, then the next. The first map that has the key wins.

from collections import ChainMap

defaults = {"colour": "blue", "size": "M"}
user = {"size": "L"}
settings = ChainMap(user, defaults)
print(settings["colour"])
print(settings["size"])
print(dict(settings))

Writes go to the first map

Saving a key writes into the first dict only. The defaults behind it do not change.

settings["colour"] = "red"
print(user)
print(defaults)

Example

from collections import deque, ChainMap

jobs = deque()
jobs.append("report.pdf")
jobs.append("photo.png")
jobs.append("notes.txt")
print("Next job:", jobs.popleft())
print("Waiting:", list(jobs))
base = {"theme": "light", "font": "small"}
custom = {"font": "large"}
config = ChainMap(custom, base)
print("theme:", config["theme"])
print("font:", config["font"])

Key points

  • deque: a sequence built for fast adding and removing at both ends
  • Use popleft() to take the front item, like serving the first person in line
  • namedtuple: a tuple with named fields, such as x and y
  • ChainMap: a view that layers several dicts and searches them in order
  • Use ChainMap to layer user settings over default settings
  • Writing to a ChainMap changes only its first dict

In this example, jobs starts as an empty deque. Three append calls add print jobs at the right end. The popleft call takes the oldest job from the left end. The print of the list shows the two jobs still waiting. Next, base holds the default settings. The custom dict holds only one changed setting. ChainMap layers custom over base. The theme lookup falls through to base. The font lookup finds large in custom first.

Note

The dicts behind it stay untouched.

Try it Yourself

Edit the code, then press Run.

Running is simulated · Python Playground

Exercise

In ChainMap(user, defaults), where does a lookup look first?