Updated efficient lookup based on uszipcode
Project description
ZipSearch
Ultra-fast US zipcode lookup library with 100% backwards compatibility
ZipSearch is a drop-in replacement for uszipcode that delivers >600x faster zipcode lookups and >50,000x faster city/state searches by using pre-built RAM indices instead of SQLite queries.
Key Features
- Blazing Fast: RAM-based O(1) lookups instead of SQLite queries
- 100% Compatible: Drop-in replacement for
uszipcode- no code changes needed - Complete Data: All 42,724+ US zipcodes with demographics, coordinates, and boundaries
- Multiple Search Types: By zipcode, city/state, coordinates, prefix, and more
- Batch Processing: Optimized methods for bulk operations
- Memory Efficient: Pre-built indices loaded once at startup (11mb)
Performance Comparison
Installation
pip install zipsearch
Quick Start
Basic Usage (100% compatible with uszipcode)
from zipsearch import SearchEngine
search = SearchEngine()
# Zipcode lookup
zipcode = search.by_zipcode("10001")
print(f"{zipcode.major_city}, {zipcode.state}") # New York, NY
# City and state lookup
zipcodes = search.by_city_and_state("Chicago", "IL")
print(f"Found {len(zipcodes)} zipcodes in Chicago")
# Coordinate-based search
nearby = search.by_coordinates(40.7128, -74.0060, radius=5)
print(f"Found {len(nearby)} zipcodes within 5 miles of NYC")
Advanced Usage
from zipsearch import FastSearchEngine
engine = FastSearchEngine()
# Batch processing for DataFrames
city_state_pairs = [("New York", "NY"), ("Los Angeles", "CA"), ("Chicago", "IL")]
results = engine.batch_city_state_lookup(city_state_pairs)
# Prefix search
manhattan_zips = engine.by_prefix("100") # All 100xx zipcodes
# State-wide search
california_zips = engine.by_state("California")
Complete API Reference
SearchEngine (Backwards Compatible)
search = SearchEngine()
# Single zipcode lookup
zipcode = search.by_zipcode("90210")
# City and state (handles full state names and abbreviations)
zipcodes = search.by_city_and_state("Beverly Hills", "California")
zipcodes = search.by_city_and_state("Beverly Hills", "CA")
# Coordinate search with radius (miles)
nearby = search.by_coordinates(34.0901, -118.4065, radius=10)
# Legacy query method (limited compatibility)
results = search.query(city="Austin", state="TX")
FastSearchEngine (New Optimized API)
engine = FastSearchEngine()
# All the same methods as SearchEngine, plus:
results = engine.by_city("Austin") # Search by city across all states
results = engine.by_state("TX") # All zipcodes in a state
results = engine.by_prefix("787") # All zipcodes starting with 787
# Batch operations for ETL/DataFrame processing
batch_results = engine.batch_city_state_lookup([
("Austin", "TX"),
("Houston", "TX"),
("Dallas", "TX")
])
📊 Zipcode Data Fields
Each zipcode object contains comprehensive demographic and geographic data:
zipcode = search.by_zipcode("10001")
# Geographic
print(zipcode.lat, zipcode.lng) # 40.7505, -73.9934
print(zipcode.timezone) # Eastern
print(zipcode.radius_in_miles) # 0.9090
# Administrative
print(zipcode.major_city) # New York
print(zipcode.county) # New York County
print(zipcode.state) # NY
print(zipcode.zipcode_type) # STANDARD
# Demographics
print(zipcode.population) # 21102
print(zipcode.population_density) # 23227.0
print(zipcode.median_home_value) # 1000000
print(zipcode.median_household_income) # 85066
# Area
print(zipcode.land_area_in_sqmi) # 0.91
print(zipcode.water_area_in_sqmi) # 0.0
# Boundaries
print(zipcode.bounds) # {'west': -74.0, 'east': -73.98, ...}
# Lists (JSON decoded)
print(zipcode.common_city_list) # ['New York']
print(zipcode.area_code_list) # ['212', '646', '332']
Migration from uszipcode
No code changes required! Simply replace the import:
# Before
from uszipcode import SearchEngine
# After
from zipsearch import SearchEngine
# Everything else stays the same
search = SearchEngine()
zipcode = search.by_zipcode("10001")
Performance Optimization Tips
For maximum performance in data processing workflows:
# Use FastSearchEngine for new code
from zipsearch import FastSearchEngine
engine = FastSearchEngine()
# Use batch methods for DataFrame enrichment
results = engine.batch_city_state_lookup(city_state_pairs)
# Pre-load the engine once, reuse many times
class DataProcessor:
def __init__(self):
self.zipcode_engine = FastSearchEngine() # Load once
def enrich_dataframe(self, df):
# Use self.zipcode_engine for all lookups
pass
Technical Architecture
How It Works
- Pre-built Indices: All zipcode data is pre-processed into optimized Python dictionaries
- Memory Loading: Indices are loaded once at startup using pickle
- O(1) Lookups: Direct dictionary access instead of SQL queries
- Smart Indexing: Multiple index types for different search patterns:
zipcode_index: Direct zipcode → data mappingcity_state_index: (city, state) → [zipcodes] mappingcoordinate_grid: Spatial grid for geographic searches
Memory Usage
- Index Size: ~50MB RAM for all US zipcode data
- Load Time: ~100ms initial startup
- Lookup Time: ~0.0003ms per operation
Data Sources
- Based on the same comprehensive dataset as
uszipcode - 42,724+ zipcodes with complete demographic and geographic data
- Regular updates to maintain data accuracy
Requirements
- Python 3.7+
- No external dependencies for core functionality
- Compatible with pandas, numpy, and other data science libraries
Benchmarks
Our comprehensive benchmarks show consistent performance improvements:
=== Zipcode Lookups ===
uszipcode: 100,000 ops in 17.57s (5,692 ops/sec)
zipsearch: 1,000,000 ops in 0.26s (3,827,112 ops/sec)
Speedup: 670x faster
=== City/State Lookups ===
uszipcode: 2,500 ops in 74.36s (34 ops/sec)
zipsearch: 1,000,000 ops in 0.58s (1,740,366 ops/sec)
Speedup: 51,674x faster
License
MIT License - see LICENSE file for details.
Acknowledgments
- Original
uszipcodelibrary for the comprehensive dataset and API design - US Census Bureau for demographic data
- USPS for zipcode definitions
⚡ Ready to make your zipcode lookups 670x faster? Install zipsearch today!
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file zipsearch-1.1.0.tar.gz.
File metadata
- Download URL: zipsearch-1.1.0.tar.gz
- Upload date:
- Size: 3.7 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.8.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7d7bf8c01ae545cbad6f6ff4e875f26be68b96477ec0b346a85b0032b3242024
|
|
| MD5 |
91ca5b3ff6af7906ce1c08f94e3d498f
|
|
| BLAKE2b-256 |
08611288dd78289dd8b9c49661055f5b99bb55f5bd7686ef491551ea10707c67
|
File details
Details for the file zipsearch-1.1.0-py3-none-any.whl.
File metadata
- Download URL: zipsearch-1.1.0-py3-none-any.whl
- Upload date:
- Size: 3.7 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.8.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3a2b66cea880ba556f767d07156462abef7e34f68b8ad51accf449f0f1a2ac57
|
|
| MD5 |
5d2f5f331d7deaf58c30016247b8c1e1
|
|
| BLAKE2b-256 |
6debd0fda8cda59007082a1de1840c6aa89ce53bc131598bb07c67bc1e22d08b
|