Windows · Python 3.12.4. 본문의 첫 예제를 실행하여 표준 출력과 예상 결과가 일치함을 확인했습니다. 연습문제의 모든 입력을 검증한 것은 아닙니다.
이 글의 순서 4개 단락
주문 상품명에 쉼표가 들어 있으면 쉼표마다 문자열을 나누는 것만으로는 열을 제대로 읽을 수 없습니다. CSV는 값 전체를 따옴표로 감싸 그 안의 쉼표가 구분자가 아니라 값의 일부임을 나타낼 수 있습니다.
같은 주문 데이터를 두 방법으로 읽기
환경: Python 3.12. 다음 예제는 주문 CSV를 문자열로 직접 만들므로 준비할 파일이 없습니다. 첫 주문의 상품명은 연필, 지우개이고, 두 번째 주문의 수량은 비어 있습니다. 예제는 같은 첫 데이터 행을 split과 csv.reader로 비교한 다음, 전체 주문을 읽어 수량 합계가 담긴 요약 CSV를 메모리에 만듭니다.
import csv
import io
orders_csv = '''order_id,product,quantity
101,"연필, 지우개",2
102,노트,
103,펜,3
'''
first_order = orders_csv.splitlines()[1]
print("split:", first_order.split(","))
rows = list(csv.reader(io.StringIO(orders_csv, newline="")))
print("csv.reader:", rows[1])
order_count = 0
quantity_total = 0
for order_id, product, quantity in rows[1:]:
order_count += 1
quantity_total += int(quantity) if quantity.strip() else 0
summary = io.StringIO(newline="")
writer = csv.writer(summary, lineterminator="\n")
writer.writerow(["order_count", "quantity_total"])
writer.writerow([order_count, quantity_total])
print("요약 CSV:")
print(summary.getvalue(), end="")

입력은 코드 안의 세 주문이며, 예상 표준 출력은 다음과 같습니다.
split: ['101', '"연필', ' 지우개"', '2']
csv.reader: ['101', '연필, 지우개', '2']
요약 CSV:
order_count,quantity_total
3,5
split은 첫 주문을 네 조각으로 만들지만 csv.reader는 세 열로 읽습니다. 빈 수량을 0으로 계산하므로 전체 주문은 세 건, 수량 합계는 5입니다.
따옴표와 빈 값 처리하기
split(',')은 쉼표의 위치만 보고 자릅니다. 반면 csv.reader는 기본 CSV 형식에서 큰따옴표로 감싼 필드를 하나의 값으로 읽고, 필드를 감싼 따옴표를 제거합니다. 필드 안의 큰따옴표는 CSV에서 두 개를 연속해 표현할 수 있습니다. 예를 들어 "큰 ""공책"", 파랑"은 큰 "공책", 파랑이라는 하나의 값으로 읽힙니다.
csv.reader가 반환하는 각 필드는 기본적으로 문자열입니다. 빈 수량도 None이 아니라 빈 문자열 ''이므로 바로 int()에 넣으면 오류가 납니다. 예제에서는 quantity.strip()이 비어 있으면 0으로 계산하고, 그 외에는 정수로 변환합니다. 이는 이 실습의 규칙입니다. 실제 업무에서 빈 수량이 미확인을 뜻한다면 0으로 바꾸지 말고 별도로 확인해야 합니다.
열이 부족하거나 많으면 세 변수로 나누어 받는 부분에서 오류가 나고, 수량이 두 개처럼 정수가 아닌 문자열이면 int()에서 오류가 납니다. 실제 입력을 처리할 때는 열 개수와 수량을 검증하고 오류 행을 따로 알려 주세요. 필드 안에 줄바꿈이 들어갈 수도 있으므로 전체 CSV를 읽을 때는 splitlines()로 행을 먼저 분리하는 대신 파일이나 StringIO를 csv.reader에 직접 전달합니다. 위의 splitlines()는 단순 분할이 실패하는 첫 행을 보여 주기 위한 것입니다.
요약 CSV를 파일로 저장하기
첫 예제의 summary는 메모리 안의 텍스트 스트림입니다. 실행 후 같은 프로그램의 끝에 다음 코드를 추가하면 요약 내용을 현재 작업 디렉터리의 order_summary.csv에 저장합니다. 같은 이름의 파일이 있으면 덮어씁니다.
with open("order_summary.csv", "w", encoding="utf-8", newline="") as output_file:
output_file.write(summary.getvalue())
저장되는 파일에는 order_count,quantity_total 헤더와 3,5 데이터 행이 들어갑니다. 앞서 csv.writer가 CSV 형식의 문자열을 만들었기 때문에 파일에는 그 결과를 그대로 씁니다. 파일을 csv.writer에 직접 전달할 수도 있으며, 이때도 CSV 문서의 권장대로 파일을 newline=''로 엽니다. csv.writer를 사용하면 쉼표나 따옴표가 들어 있는 값을 직접 이어 붙여 CSV를 만드는 실수를 줄일 수 있습니다.
작은 연습: 쉼표가 들어 있는 요약 항목
요약 CSV에 note 열을 추가하고 값을 문구, 사무용으로 기록해 보세요. 쉼표가 들어간 값이 한 열로 유지되어야 합니다.
풀이: 첫 예제의 두 writer.writerow 호출을 다음과 같이 바꿉니다.
writer.writerow(["order_count", "quantity_total", "note"])
writer.writerow([order_count, quantity_total, "문구, 사무용"])
예상되는 요약 CSV는 다음과 같습니다. csv.writer가 쉼표가 들어간 값을 따옴표로 감싸므로 다시 csv.reader로 읽으면 note는 한 열입니다.
order_count,quantity_total,note
3,5,"문구, 사무용"CHECK THE SOURCE
참고한 공식 문서
기능 설명은 위 문서를 참고했으며, 예제의 입력·결과와 한계는 본문에 따로 기록했습니다.