Missing keys: get and safe defaults
APIs leave keys out when there is nothing to say. `get` reads a key that may be missing and gives back a default instead of stopping the program.
- Use
record.get(key)andrecord.get(key, default)and say what each returns for a missing key - Explain why a key that holds
Nonedoes not use the default - Chain
getwith a{}default to reach safely into a dictionary that may be missing
In the USGS feed, an earthquake nobody reported feeling has "felt": null (None in Python), and some sources leave keys such as tsunami out entirely. Customer records are the same: a phone number that was never entered isn't stored as an empty value, the key just isn't there.
Brackets demand the key: props["tsunami"] stops the program with KeyError when it is missing. The dictionary method `get` asks instead: props.get("tsunami") returns None when the key is missing, and props.get("tsunami", 0) returns the default you chose.
Run each example to see what it prints. Running examples doesn't count toward progress.
props = {"mag": 4.6, "place": "44 km WSW of Cabangahan, Philippines", "felt": 1, "alert": None}
print(props.get("felt"))
print(props.get("tsunami"))
print(props.get("tsunami", 0))
print(props.get("alert", "none issued"))props = {"mag": 4.6, "felt": 1}
print(props["felt"])
print(props["tsunami"])When a whole inner dictionary can be missing, give get an empty dictionary as the default. feature.get("properties", {}) always returns a dictionary, so the next get is safe either way. When None and "missing" should mean the same thing, test the result with is None and choose the value yourself.
def felt_reports(feature): props = feature.get("properties", {}) felt = props.get("felt") if felt is None: return 0 return felt features = [ {"id": "us6000pw8f", "properties": {"mag": 4.6, "felt": 1}}, {"id": "us6000pw77", "properties": {"mag": 4.7, "felt": None}}, {"id": "nc75123456"}, ] for f in features: print(f["id"], felt_reports(f))
When to use it: for keys the data is allowed to leave out: optional profile fields, flags that only appear when set, nested sections that some records don't have. Mistakes to avoid: expecting the default when the key holds None; using get for a key that must exist, which hides a broken record behind a None that fails somewhere later; and writing props.get["felt"] with brackets instead of parentheses (get is a method you call).
d.get(k)returns None for a missing key;d.get(k, default)returns your default.- A key that holds None is not missing:
getreturns None, not the default. d.get("inner", {})lets you keep chaining when a whole section may be absent.- Next: records often hold lists, such as an order's line items. An inner loop walks them.