Python zip() Function Explained: A Data Engineering Use Case
Table of Contents
Overview
Python’s zip() function combines elements from multiple iterables (such as lists or dictionaries) into pairs. Think of it like a zipper on a jacket: it takes two separate sides and locks them together, one element at a time.
Get Yan Li’s stories in your inbox
Join Medium for free to get updates from this writer.
Two things to keep in mind:
- By default,
zip()stops when the shortest iterable runs out of elements zip()is lazy, meaning it returns an iterator, not a list. To see the result, wrap it withlist()
numbers = [1, 2, 3]
letters = ["a", "b", "c"]
zipped = zip(numbers, letters)
print(zipped) # <zip object at 0x......>
print(list(zipped)) # [(1, 'a'), (2, 'b'), (3, 'c')]Real-World Example: ETL Type Mapping with zip()
As a data engineer, let’s say we will move data from a source database like PostgreSQL into a data warehouse like Amazon Redshift. One task during this ETL process is mapping data types from the source to the target, because the two systems use different type names. For example:
Without zip()
You need an index i to access both lists separately:
def map_pg_to_redshift(field_names: list[str], field_types: list[str]) -> dict[str, str]:
column_types = {}
for i in range(len(field_names)):
name = field_names[i]
pg_type = field_types[i]
if pg_type == "TEXT":
column_types[name] = "VARCHAR(256)"
elif pg_type == "JSONB":
column_types[name] = "SUPER"
elif pg_type.startswith("NUMERIC"):
column_types[name] = "DECIMAL(18,2)"
else:
column_types[name] = pg_type
return column_typesWith zip()
You pair field_names and field_types directly in the loop header, removing the index entirely
def map_pg_to_redshift(field_names: list[str], field_types: list[str]) -> dict[str, str]:
column_types = {}
for name, pg_type in zip(field_names, field_types):
if pg_type == "TEXT":
column_types[name] = "VARCHAR(256)"
elif pg_type == "JSONB":
column_types[name] = "SUPER"
elif pg_type.startswith("NUMERIC"):
column_types[name] = "DECIMAL(18,2)"
else:
column_types[name] = pg_type
return column_types
pg_columns = ["username", "event_payload", "price"]
pg_types = ["TEXT", "JSONB", "NUMERIC"]
result = map_pg_to_redshift(pg_columns, pg_types)Both versions return the same result, a dict where each key is a column name and each value is its mapped Redshift data type
{
'username': 'VARCHAR(256)',
'event_payload': 'SUPER',
'price': 'DECIMAL(18,2)'
}Why zip() Is Better
- Readability: the loop header immediately tells you what you are working with: a
nameand apg_type. There is no index to trace. - Safety: passing
strict=Truetozip()raises aValueErrorimmediately if the two lists have different lengths, catching data misalignment bugs early. (Requires Python 3.10 or later) - Flexibility:
zip()works with any iterables, not just lists that support index access.
Quick Visual Recap
Thanks for taking the time to read this article. If you learned something new, then please give it a clap. If you think others may find it helpful, then feel free to share it. If you want to stay updated with my future content, then hit the follow button. If you have any questions or comments, then drop them below. I’ll reply ASAP. Thanks for your support!








