파이썬 딕셔너리파이썬 리스트파이썬
광고 데이터를 코드 안에 담는 법: 딕셔너리·리스트·집합
그로스앤디 · 2026-08-24 발행· 7분 읽기
목차
앞선 글에서 프로그램은 JSON 파일을 읽어 Python 객체로 바꾼다고 설명했어요. 그렇다면 파일에서 들어온 목표와 캠페인은 코드 안에서 어디에 담길까요?
광고 캠페인 성과 진단기에는 딕셔너리, 리스트, 집합이 함께 사용됩니다. 세 자료구조는 비슷한 데이터를 담는 대체재가 아니라 서로 다른 질문에 답하는 도구예요.
딕셔너리: 한 대상은 어떤 속성을 가졌는가?
리스트: 여러 대상을 어떤 순서로 처리할 것인가?
집합: 이 값이 이미 등장했는가?
자료구조를 선택한다는 것은 현실의 업무를 코드 안에서 어떤 모양으로 표현할지 결정하는 일입니다.
캠페인 하나는 딕셔너리입니다
캠페인 하나에는 이름·광고비·노출·클릭·전환·매출이 함께 속합니다.
campaign = {
"campaign": "여름 세일",
"spend": 300000,
"impressions": 50000,
"clicks": 1200,
"conversions": 34,
"revenue": 1050000,
}
딕셔너리는 키: 값의 관계로 데이터를 담습니다.
| 키 | 값 | 업무 의미 |
|---|---|---|
campaign |
여름 세일 | 캠페인 이름 |
spend |
300000 | 광고비 |
impressions |
50000 | 노출 수 |
clicks |
1200 | 클릭 수 |
conversions |
34 | 전환 수 |
revenue |
1050000 | 매출 |
값의 순서를 외우지 않아도 키를 이용해 필요한 데이터를 찾을 수 있습니다.
campaign["spend"]
campaign["conversions"]
campaign["spend"]는 “이 캠페인의 광고비”라는 의미를 코드 안에서도 그대로 드러냅니다.
목표도 딕셔너리입니다
목표 ROAS와 CPA는 캠페인의 성과를 판단하는 하나의 기준 묶음입니다.
goals = {
"target_roas": 300,
"target_cpa": 20000,
}
캠페인과 목표는 모두 딕셔너리지만 역할은 다릅니다.
campaign: 실제로 발생한 성과 데이터goals: 성과를 비교할 기준 데이터
이 둘을 evaluate_performance(metrics, goals)에 함께 전달하면 실제 성과가 목표를 충족했는지 판정할 수 있습니다.
여러 캠페인은 리스트에 담습니다
캠페인 하나를 딕셔너리로 표현했다면, 여러 캠페인은 리스트로 묶습니다.
campaigns = [
{"campaign": "여름 세일", "spend": 300000, ...},
{"campaign": "신규 고객 리타겟팅", "spend": 180000, ...},
{"campaign": "브랜드 검색", "spend": 120000, ...},
]
리스트를 사용하면 캠페인을 앞에서부터 하나씩 반복할 수 있습니다.
for campaign in campaigns:
errors = validate_campaign(campaign, seen_names)
새 캠페인이 추가돼도 검증 코드를 복사할 필요가 없습니다. 리스트에 캠페인 딕셔너리 하나를 더 넣으면 같은 반복 규칙이 적용됩니다.
리스트가 여러 캠페인을 하나의 처리 흐름으로 묶기 때문에, 캠페인 수가 달라져도 코드는 같은 일을 반복할 수 있습니다.
필수 항목도 리스트로 관리합니다
모든 캠페인이 가져야 하는 키는 REQUIRED_FIELDS에 모아두었습니다.
REQUIRED_FIELDS = [
"campaign",
"spend",
"impressions",
"clicks",
"conversions",
"revenue",
]
검증 함수는 이 리스트를 순회하며 빠진 항목을 찾습니다.
missing_fields = [
field for field in REQUIRED_FIELDS if campaign.get(field) is None
]
필수 항목을 코드 여러 곳에 반복해서 적는 대신 한 곳에서 관리할 수 있어요. 나중에 필수 필드가 바뀌어도 REQUIRED_FIELDS를 먼저 확인하면 됩니다.
.get()과 대괄호는 언제 다르게 사용할까
딕셔너리의 값은 두 방식으로 꺼낼 수 있습니다.
campaign["spend"]
campaign.get("spend")
대괄호는 키가 없으면 KeyError를 발생시킵니다. .get()은 키가 없으면 기본적으로 None을 돌려줍니다.
이 프로그램은 검증 전에는 .get()을 사용합니다.
name = campaign.get("campaign")
누락값을 찾는 과정에서 프로그램이 먼저 멈추지 않도록 하기 위해서예요. 반대로 검증을 통과한 뒤 계산할 때는 필수 키가 있다고 믿고 대괄호를 사용합니다.
campaign["clicks"] / campaign["impressions"]
검증 전이라면, 코드가 없을 가능성을 염두해두고 에러 가능성을 사전에 차단합니다. 검증 후라면, 확인된 데이터 규칙을 그대로 활용하는 방식으로 안정성을 높이죠.
중복 이름은 집합으로 기억하기
리스트는 모든 캠페인을 보관하는 데 적합하지만, 어떤 이름이 이미 나왔는지 빠르게 확인하려면 집합을 사용합니다.
seen_names = set()
캠페인명을 공백 제거와 소문자 변환으로 정규화한 뒤 집합에서 확인합니다.
normalized_name = name.strip().lower()
if normalized_name in seen_names:
errors.append(f"중복 캠페인명: {name.strip()}")
else:
seen_names.add(normalized_name)
"Summer Sale"과 " summer sale "처럼 표기가 조금 달라도 같은 이름으로 판정할 수 있습니다.
집합은 같은 값을 중복해서 보관하지 않기 때문에
“이미 등장했는가?”라는 질문과 잘 맞습니다.
처리 결과도 다시 자료구조가 됩니다
진단 과정에서는 새로운 리스트와 딕셔너리가 만들어집니다.
results = []
valid_campaigns = []
results: 정상 결과와 입력 오류를 모두 담는 리스트valid_campaigns: 전체 요약에 사용할 정상 캠페인만 담는 리스트
캠페인 한 건의 결과도 딕셔너리입니다.
{
"number": 1,
"campaign": "여름 세일",
"status": "목표 달성",
"metrics": {
"ctr": 2.4,
"cvr": 2.83,
"cpc": 250,
"cpa": 8823.53,
"roas": 350,
},
}
입력과 출력은 내용이 다르지만 모두 딕셔너리와 리스트를 조합해 표현됩니다.
데이터 구조를 그림으로 다시 보겠습니다
전체 데이터: dict
├── goals: dict
│ ├── target_roas
│ └── target_cpa
└── campaigns: list
├── 캠페인 1: dict
├── 캠페인 2: dict
└── 캠페인 3: dict
검증 과정
├── REQUIRED_FIELDS: list
├── errors: list
└── seen_names: set
진단 결과
├── results: list
└── valid_campaigns: list
예제 JSON을 열고 각 괄호 옆에 dict, list, set을 직접 표시해보세요. 그다음 다음 질문에 답해보면 됩니다.
- 캠페인 하나를 리스트로 만들면 어떤 값을 찾기 어려워질까?
- 여러 캠페인을 딕셔너리 하나에 모두 넣으면 반복하기 쉬울까?
- 중복 이름 확인에 리스트보다 집합이 어울리는 이유는 무엇일까?
좋은 자료구조는 데이터의 의미와 다음 처리 방법을 분명하게 만든다는 점, 항상 잊지 마세요
다음 글인 잘못된 광고 데이터를 막는 검증과 예외 처리에서는 이 구조에 담긴 데이터가 계산에 사용해도 되는지 확인합니다. JSON 문법은 맞지만 광고 데이터로는 틀린 값을 어떻게 찾아내는지 살펴볼게요.
관련 키워드
파이썬 딕셔너리파이썬 리스트파이썬 집합Python 자료구조광고 데이터