목록

Python zip() 함수 완벽 가이드

회원 직접 작성 · 2026-08-27 13:17
Python zip() 함수 완벽 가이드

이 기사를 내 블로그에 포스팅하려면 로그인이 필요합니다.

아직 AI 요약이 생성되지 않았습니다.

포스팅 원고

Python zip() 함수 완벽 가이드

Python의 내장 함수 zip()은 여러 개의 리스트(또는 반복 가능한 객체)를 같은 인덱스끼리 묶어주는 함수입니다. 실무에서 정말 자주 쓰이는 함수인데도 의외로 헷갈리는 부분이 많아서, 기본 사용법부터 가짜 이름/주소 생성 실전 예제까지 정리해봤습니다.


1. zip()이란?

zip(*iterables)

여러 개의 반복 가능한 객체를 받아서, 같은 인덱스에 있는 요소들끼리 묶어 튜플(tuple)로 반환하는 이터레이터입니다.

names = ["철수", "영희", "민수"]
ages  = [20, 22, 25]

result = zip(names, ages)
print(list(result))

[('철수', 20), ('영희', 22), ('민수', 25)]

zip()의 반환값은 이터레이터이기 때문에, 화면에 출력하거나 값을 재사용하려면 list()로 감싸줘야 합니다. 한 번 순회하면 소진되어 다시 사용할 수 없습니다.


2. for문과 함께 사용하기

가장 많이 쓰이는 패턴입니다.

names = ["철수", "영희", "민수"]
ages  = [20, 22, 25]

for name, age in zip(names, ages):
    print(f"{name}는 {age}살입니다.")

철수는 20살입니다.
영희는 22살입니다.
민수는 25살입니다.


3. 딕셔너리 만들기

keys = ["a", "b", "c"]
values = [1, 2, 3]

d = dict(zip(keys, values))
print(d)

{'a': 1, 'b': 2, 'c': 3}


4. 길이가 다른 리스트를 묶을 때

zip()가장 짧은 리스트를 기준으로 묶고, 나머지는 버립니다.

a = [1, 2, 3, 4, 5]
b = ['x', 'y', 'z']

print(list(zip(a, b)))

[(1, 'x'), (2, 'y'), (3, 'z')]

a4, 5는 짝이 없으므로 무시됩니다.

짧은 쪽을 특정 값으로 채워서 끝까지 묶고 싶다면 itertools.zip_longest()를 사용하세요.

from itertools import zip_longest

a = [1, 2, 3, 4, 5]
b = ['x', 'y', 'z']

print(list(zip_longest(a, b, fillvalue=None)))

[(1, 'x'), (2, 'y'), (3, 'z'), (4, None), (5, None)]


5. 3개 이상의 리스트도 묶을 수 있다

a = [1, 2, 3]
b = ['x', 'y', 'z']
c = [True, False, True]

print(list(zip(a, b, c)))

[(1, 'x', True), (2, 'y', False), (3, 'z', True)]


6. Unzip: 묶인 것을 다시 풀기

zip(*결합된리스트)를 사용하면 다시 원래대로 풀 수 있습니다.

pairs = [(1, 'a'), (2, 'b'), (3, 'c')]

numbers, letters = zip(*pairs)

print(numbers)   # (1, 2, 3)
print(letters)   # ('a', 'b', 'c')

결과가 튜플로 반환되므로, 리스트가 필요하면 list()로 다시 감싸야 합니다.


7. 리스트 컴프리헨션 / enumerate와 함께 쓰기

a = [1, 2, 3]
b = [10, 20, 30]

sums = [x + y for x, y in zip(a, b)]
print(sums)   # [11, 22, 33]

names = ["철수", "영희", "민수"]
ages  = [20, 22, 25]

for i, (name, age) in enumerate(zip(names, ages)):
    print(f"{i}: {name} - {age}세")


8. 실전 예제: Fake Name / Fake Address 생성 후 zip으로 묶기

8-1. 표준 라이브러리만으로 만들기

외부 패키지 없이 random 모듈만으로 그럴듯한 가짜 이름과 주소를 만들 수 있습니다.

import random

first_names = ["민준", "서연", "도윤", "지우", "하윤", "예준"]
last_names  = ["김", "이", "박", "최", "정", "강"]

cities   = ["서울", "부산", "대구", "인천", "광주", "대전"]
streets  = ["테헤란로", "강남대로", "월드컵로", "해운대로", "중앙로"]

def make_fake_name():
    return random.choice(last_names) + random.choice(first_names)

def make_fake_address():
    city = random.choice(cities)
    street = random.choice(streets)
    number = random.randint(1, 200)
    return f"{city}시 {street} {number}"

names = [make_fake_name() for _ in range(5)]
addresses = [make_fake_address() for _ in range(5)]

people = list(zip(names, addresses))
for name, address in people:
    print(f"{name} - {address}")

출력 예시 (random이므로 실행할 때마다 달라짐)

김민준 - 서울시 테헤란로 84
이서연 - 부산시 해운대로 12
박도윤 - 대구시 중앙로 173
최지우 - 인천시 강남대로 46
정하윤 - 광주시 월드컵로 91

8-2. Faker 라이브러리로 더 실전적인 가짜 데이터 만들기

pip install faker

from faker import Faker

fake = Faker("ko_KR")   # 한국어 로케일

names = [fake.name() for _ in range(5)]
addresses = [fake.address() for _ in range(5)]

people = list(zip(names, addresses))
for name, address in people:
    print(f"{name} - {address}")

Faker("en_US")처럼 로케일을 바꾸면 영어 이름/주소도 생성할 수 있습니다.

8-3. list[dict] 형태로 정리하기 (실무 패턴)

records = [
    {"name": name, "address": address}
    for name, address in zip(names, addresses)
]

for r in records:
    print(r)

{'name': '김민준', 'address': '서울시 테헤란로 84'}
{'name': '이서연', 'address': '부산시 해운대로 12'}
...

이 형태는 JSON 저장, DB 삽입 등에 바로 활용하기 좋습니다.

8-4. CSV로 저장하기

import csv

with open("fake_people.csv", "w", newline="", encoding="utf-8-sig") as f:
    writer = csv.writer(f)
    writer.writerow(["name", "address"])
    writer.writerows(zip(names, addresses))

zip(names, addresses)writerows()에 바로 넣을 수 있다는 점이 포인트입니다.


9. 주의사항 정리

  • zip()의 반환값은 이터레이터이며, 한 번 순회하면 소진됩니다.

  • 리스트 길이가 다르면 짧은 쪽 기준으로 잘립니다. (모두 유지하려면 itertools.zip_longest 사용)

  • zip() 결과 자체는 리스트가 아니라 튜플들의 나열입니다. 리스트가 필요하면 list(zip(...))로 변환하세요.

  • 인자 없이 zip()만 호출하면 빈 이터레이터를 반환합니다.

  • 이름을 딕셔너리의 key로 쓸 경우 중복되면 값이 덮어씌워지므로 주의가 필요합니다.


10. 요약 표

목적

코드

기본 묶기

list(zip(a, b))

for문 순회

for x, y in zip(a, b):

딕셔너리 생성

dict(zip(keys, values))

길이 다를 때 채우기

zip_longest(a, b, fillvalue=0)

여러 개 묶기

zip(a, b, c)

묶은 것 다시 풀기

zip(*pairs)

가짜 이름/주소 생성 (외부 X)

random.choice()로 조합

가짜 이름/주소 생성 (실전용)

Faker 라이브러리 사용

리스트[dict]로 변환

[{...} for a, b in zip(...)]

CSV로 저장

csv.writer().writerows(zip(...))



📄 원문 전문
Python zip() 함수 완벽 가이드 Python의 내장 함수 zip()은 여러 개의 리스트(또는 반복 가능한 객체)를 같은 인덱스끼리 묶어주는 함수입니다. 실무에서 정말 자주 쓰이는 함수인데도 의외로 헷갈리는 부분이 많아서, 기본 사용법부터 가짜 이름/주소 생성 실전 예제까지 정리해봤습니다. 1. zip()이란? zip(*iterables) 여러 개의 반복 가능한 객체를 받아서, 같은 인덱스에 있는 요소들끼리 묶어 튜플(tuple)로 반환하는 이터레이터입니다. names = ["철수", "영희", "민수"] ages = [20, 22, 25] result = zip(names, ages) print(list(result)) [('철수', 20), ('영희', 22), ('민수', 25)] zip()의 반환값은 이터레이터이기 때문에, 화면에 출력하거나 값을 재사용하려면 list()로 감싸줘야 합니다. 한 번 순회하면 소진되어 다시 사용할 수 없습니다. 2. for문과 함께 사용하기 가장 많이 쓰이는 패턴입니다. names = ["철수", "영희", "민수"] ages = [20, 22, 25] for name, age in zip(names, ages): print(f"{name}는 {age}살입니다.") 철수는 20살입니다. 영희는 22살입니다. 민수는 25살입니다. 3. 딕셔너리 만들기 keys = ["a", "b", "c"] values = [1, 2, 3] d = dict(zip(keys, values)) print(d) {'a': 1, 'b': 2, 'c': 3} 4. 길이가 다른 리스트를 묶을 때 zip()은 가장 짧은 리스트를 기준으로 묶고, 나머지는 버립니다. a = [1, 2, 3, 4, 5] b = ['x', 'y', 'z'] print(list(zip(a, b))) [(1, 'x'), (2, 'y'), (3, 'z')] a의 4, 5는 짝이 없으므로 무시됩니다. 짧은 쪽을 특정 값으로 채워서 끝까지 묶고 싶다면 itertools.zip_longest()를 사용하세요. from itertools import zip_longest a = [1, 2, 3, 4, 5] b = ['x', 'y', 'z'] print(list(zip_longest(a, b, fillvalue=None))) [(1, 'x'), (2, 'y'), (3, 'z'), (4, None), (5, None)] 5. 3개 이상의 리스트도 묶을 수 있다 a = [1, 2, 3] b = ['x', 'y', 'z'] c = [True, False, True] print(list(zip(a, b, c))) [(1, 'x', True), (2, 'y', False), (3, 'z', True)] 6. Unzip: 묶인 것을 다시 풀기 zip(*결합된리스트)를 사용하면 다시 원래대로 풀 수 있습니다. pairs = [(1, 'a'), (2, 'b'), (3, 'c')] numbers, letters = zip(*pairs) print(numbers) # (1, 2, 3) print(letters) # ('a', 'b', 'c') 결과가 튜플로 반환되므로, 리스트가 필요하면 list()로 다시 감싸야 합니다. 7. 리스트 컴프리헨션 / enumerate와 함께 쓰기 a = [1, 2, 3] b = [10, 20, 30] sums = [x + y for x, y in zip(a, b)] print(sums) # [11, 22, 33] names = ["철수", "영희", "민수"] ages = [20, 22, 25] for i, (name, age) in enumerate(zip(names, ages)): print(f"{i}: {name} - {age}세") 8. 실전 예제: Fake Name / Fake Address 생성 후 zip으로 묶기 8-1. 표준 라이브러리만으로 만들기 외부 패키지 없이 random 모듈만으로 그럴듯한 가짜 이름과 주소를 만들 수 있습니다. import random first_names = ["민준", "서연", "도윤", "지우", "하윤", "예준"] last_names = ["김", "이", "박", "최", "정", "강"] cities = ["서울", "부산", "대구", "인천", "광주", "대전"] streets = ["테헤란로", "강남대로", "월드컵로", "해운대로", "중앙로"] def make_fake_name(): return random.choice(last_names) + random.choice(first_names) def make_fake_address(): city = random.choice(cities) street = random.choice(streets) number = random.randint(1, 200) return f"{city}시 {street} {number}" names = [make_fake_name() for _ in range(5)] addresses = [make_fake_address() for _ in range(5)] people = list(zip(names, addresses)) for name, address in people: print(f"{name} - {address}") 출력 예시 (random이므로 실행할 때마다 달라짐) 김민준 - 서울시 테헤란로 84 이서연 - 부산시 해운대로 12 박도윤 - 대구시 중앙로 173 최지우 - 인천시 강남대로 46 정하윤 - 광주시 월드컵로 91 8-2. Faker 라이브러리로 더 실전적인 가짜 데이터 만들기 pip install faker from faker import Faker fake = Faker("ko_KR") # 한국어 로케일 names = [fake.name() for _ in range(5)] addresses = [fake.address() for _ in range(5)] people = list(zip(names, addresses)) for name, address in people: print(f"{name} - {address}") Faker("en_US")처럼 로케일을 바꾸면 영어 이름/주소도 생성할 수 있습니다. 8-3. list[dict] 형태로 정리하기 (실무 패턴) records = [ {"name": name, "address": address} for name, address in zip(names, addresses) ] for r in records: print(r) {'name': '김민준', 'address': '서울시 테헤란로 84'} {'name': '이서연', 'address': '부산시 해운대로 12'} ... 이 형태는 JSON 저장, DB 삽입 등에 바로 활용하기 좋습니다. 8-4. CSV로 저장하기 import csv with open("fake_people.csv", "w", newline="", encoding="utf-8-sig") as f: writer = csv.writer(f) writer.writerow(["name", "address"]) writer.writerows(zip(names, addresses)) zip(names, addresses)를 writerows()에 바로 넣을 수 있다는 점이 포인트입니다. 9. 주의사항 정리 zip()의 반환값은 이터레이터이며, 한 번 순회하면 소진됩니다. 리스트 길이가 다르면 짧은 쪽 기준으로 잘립니다. (모두 유지하려면 itertools.zip_longest 사용) zip() 결과 자체는 리스트가 아니라 튜플들의 나열입니다. 리스트가 필요하면 list(zip(...))로 변환하세요. 인자 없이 zip()만 호출하면 빈 이터레이터를 반환합니다. 이름을 딕셔너리의 key로 쓸 경우 중복되면 값이 덮어씌워지므로 주의가 필요합니다. 10. 요약 표 목적 코드 기본 묶기 list(zip(a, b)) for문 순회 for x, y in zip(a, b): 딕셔너리 생성 dict(zip(keys, values)) 길이 다를 때 채우기 zip_longest(a, b, fillvalue=0) 여러 개 묶기 zip(a, b, c) 묶은 것 다시 풀기 zip(*pairs) 가짜 이름/주소 생성 (외부 X) random.choice()로 조합 가짜 이름/주소 생성 (실전용) Faker 라이브러리 사용 리스트[dict]로 변환 [{...} for a, b in zip(...)] CSV로 저장 csv.writer().writerows(zip(...))