title | author | date |
---|---|---|
assignment expression use case |
Zachary Wilson |
2022-09-01 |
Nicknamed the Walrus Operator for its resemblance to the face of a Walrus: :=
, the Assignment Expression allows one to assign a value to a variable if and only if it returns a result.
Since its inception, the Assignment Expression has been a highly debated topic within the PSF.
A minimal example:
d = {"key": "value"}
if (x := d.get('key')):
print(x)
Using dict
's the get
method, dict.get
one can test for the existence of a key in a dictionary without returning an error, i.e. If the specified key doesn't exist, None
is returned.
Consider the following JSON from the U.S. Census Bureau's Geocoding Services API which takes an address (currently US only) and returns a JSON response, for example:
$ curl -fsSL "https://geocoding.geo.census.gov/geocoder/locations/onelineaddress?format=json&benchmark=Public_AR_Current&address=1500 Pennsylvania Ave Washington DC" | python -m json.tool
...
"addressMatches": [
{
"matchedAddress": "1500 PENNSYLVANIA AVE NW, WASHINGTON, DC, 20220",
"coordinates": {
"x": -77.03376,
"y": 38.89877
}
...
Assume we're only interested in collecting the x (Latitude) / y (Longitude) results and when there are no matches for a particular key, return None
rather than throwing an error -- Walrus to the rescue:
from functools import cache
import requests
@cache
def geocode(
address: str,
returntype: str = "locations",
searchtype: str = "onelineaddress",
session: requests.Session = requests.Session(),
**kwargs,
):
endpoint = f"https://geocoding.geo.census.gov/geocoder/{returntype}/{searchtype}"
params = {"format": "json", "benchmark": "Public_AR_Current"}
params.update({"address": address, **kwargs})
r = session.get(endpoint, params=params)
data = r.json()
# use assignment exp to simultaneously check for a keys existence
# and assign it's value to a variable, if it exists.
if result := data.get("result"):
if addressMatches := result.get("addressMatches"):
if firstmatch := addressMatches[0]:
return firstmatch.get("coordinates")