Advanced Tutorial

Search by City and State

You can search by city and state name, multiple results may returns. Plus, fuzzy name search is supported. Which means even the inputs has spelling problem, the fuzzy matching algorithm can still find out the city and state your are looking for, no matter using 2 letter short name or full state name.

>>> res = search.by_city_and_state(city="cicago", state="ilinoy") # smartly guess what you are looking for
>>> len(res) # matched 56 zipcode
>>> zipcode = res[0]
>>> zipcode.major_city

>>> zipcode.state_abbr

Short state name also works:

>>> res = search.by_city_and_state(city="cicago", state="il") # smartly guess what you are looking for
>>> len(res) # 56 zipcodes in Chicago
>>> zipcode = res[0]
>>> zipcode.major_city
>>> zipcode.state_abbr

You can add zipcode_type=ZipcodeType.PO_Box parameter to only include Po Box type zipcode. Or you can add zipcode_type=None to return any type of zipcode. By default, return standard type zipcode only:

>>> res = search.by_city_and_state(city="Chicago", state="IL", zipcode_type=ZipcodeType.PO_Box)

Search by City

You can search zipcode by city name.

>>> res = search.by_city("vienna")
>>> zipcode = res[0]
>>> zipcode.major_city

uszipcode also provide a internal method to help you find correct city name:

.. code-block: python
>>> search.find_city("phonix", bes_match=True)

# Find city in kensas state, state name is also typo tolerant >>> search.find_city(“kersen”, state=”kensas”, best_match=False) [“Nickerson”, ]

Search by State

You can search zipcode by state name.

>>> res = search.by_state("Rhode Island")
>>> zipcode = res[0]
>>> zipcode.state_abbr

Search by Latitude and Longitude

You can search all zipcode with-in range of XXX miles from a coordinate. You can add returns=xxx to set maximum number of zipcode can be returned. By default, it’s 5. Use returns=0 to remove the limit. The results are sorted by the distance from the center, from lowest to highest.

>>> result = search.by_coordinates(39.122229, -77.133578, radius=30)
>>> len(res) # by default 5 results returned
>>> for zipcode in result:
...     # do whatever you want...

>>> result = search.by_coordinates(39.122229, -77.133578, radius=100, returns=None)
>>> len(result) # the return limit is removed

Search by Zipcode Prefix

You can search all zipcode by its prefix:

>>> result = search.by_prefix("900")
>>> for zipcode in result:
...     print(zipcode.zipcode)

Search by Range of XXX

You can search zipcode by defining the lower bound and the upper bound of any zipcode attribute.

>>> result = search.by_population(lower=5000, upper=10000)
>>> for zipcode in result:
...     # do whatever you want...

>>> result = search.by_population_density(lower=1000, upper=2000)
>>> for zipcode in result:
...     # do whatever you want...

These attributes support range query:

Custom Query

The Zipcode and SimpleZipcode are actually sqlalchemy orm declarative base class. If you are familiar with sqlalchemy orm, you can write the query this way:

>>> import sqlalchemy as sa
>>> from uszipcode import SearchEngine, SimpleZipcode
>>> search = SearchEngine(simple_zipcode=True)
>>> sql ="10001")
SimpleZipcode(zipcode="10001", ...)

Zipcode Type

There are four type of zipcode:

  • PO Box: used only for PO Boxes at a given facility, not for any other type of delivery

  • Unique: assigned to a single high-volume address

  • Military: used to route mail for the U.S. military

  • Standard: all other ZIP Codes.

This database doesn’t have Military. And only the Standard zipcode has rich info.


By default, uszipcode only returns Standard zipcode. If you want to return PO Box or Unique zipcode, you can specify:

search.by_xxx(..., zipcode_type=ZipcodeTypeEnum.PO_Box)

If you want to return all kinds of zipcode, you can specify:

search.by_xxx(..., zipcode_type=None)

Sort Result by Attribute

Most of built-in methods support sort_by, ascending keyword (by_zipcode() suppose to return only one result).


  • sort_by: str in attribute name, for example "zipcode"``or an ORM object attribute, for example ``Zipcode.zipcode.

  • ascending: bool, True means ascending, False means descending.

# Search zipcode that average annual income per person greater than $100,000
>>> res = search.query(city="New York", state=="NY", sort_by=Zipcode.median_household_income, ascending=False)
>>> for zipcode in res:
...     print(zipcode.median_household_income) # should be in descending order

Restrict Number of Results to Return

Every search method support returns keyword to limit number of results to return. Zero is for unlimited. The default limit is 5.

Here’s an example to find the top 10 most people zipcode, sorted by population:

# Find the top 10 population zipcode
>>> res = search.by_population(upper=999999999, sort_by="population", ascending=False, returns=10)
>>> len(res)
>>> for zipcode in res:
...     print(zipcode.Population) # should be in descending order