d.get(k, default) is not d.get(k) or default
These two lines look interchangeable:
x = d.get(k, default)
x = d.get(k) or defaultThey aren't, and the gap between them is a quiet source of bugs.
d.get(k, default) returns default in exactly one situation: the key k is absent. If the key is present you get the stored value, whatever it is.
d.get(k) or default returns default whenever the stored value is falsy. In Python that isn't just None — it's 0, 0.0, "", False, [], {}, 0j, the lot. So or default fires on a whole family of perfectly valid stored values, not on absence.
It bites whenever zero, empty, or false is something you stored on purpose:
prices = {"AAPL": 0.0} # a real quote of zero
p = prices.get("AAPL") or 99.0 # -> 99.0, silently wrong
counts = {"errors": 0}
n = counts.get("errors") or 1 # -> 1, invented out of nowhere
flags = {"verbose": False}
v = flags.get("verbose") or True # -> True, the opposite of what you setIn every case get(k, default) would have returned the stored 0.0, 0, False — the truth. The or overwrites it.
The underlying point is that the two forms answer different questions. get(k, default) asks "is the key there?". or default asks "is the value truthy?". They coincide only when the default could never be a real stored value — a counter you only ever increment, say, where 0 is never written, only the missing-key case. There get(k, 0) is fine. But the moment 0 (or "", or False) is a value you might legitimately store, or collapses "absent" and "falsy" into one, and the distinction is gone.
There's a readability argument too, and it's the stronger one. d.get(k, default) is local: one line tells you the whole behaviour — fires on a missing key, full stop. d.get(k) or default is not: to know when it fires you have to read every place that writes to d and satisfy yourself that none of them ever stores a falsy value. Nearly the same characters; only one is safe to reason about in isolation.
So prefer d.get(k, default) when the default can't collide with a real value. When it can, don't paper over it: use d[k] to fail loudly on a missing key, or d.get(k) and handle the None yourself. The one form that's almost never what you want is or, because it answers a question you didn't ask.