Python으로 데이터를 다루기 시작하면 문법을 하나씩 외우는 것보다 데이터가 코드 안에서 어떻게 저장되고, 묶이고, 선택되고, 반복 처리되는지 흐름을 이해하는 것이 중요하다.
기본적인 데이터 처리 흐름은 다음처럼 생각할 수 있다.
값을 변수에 저장한다 → 여러 값을 자료구조로 묶는다 → 조건에 따라 필요한 값만 고른다 → 반복해서 처리한다 → 반복되는 로직은 함수로 분리한다.
이 글에서는 Python 입문 단계에서 데이터 처리에 직접 연결되는 문법을 하나의 흐름으로 정리한다.
변수는 값을 저장해 두고 이후 연산에서 다시 사용하기 위한 이름이다.
user_name = "seungjun"
age = 30
score = 85.23
Python은 값을 대입하는 시점에 변수의 자료형이 결정된다.
print(type(user_name))
print(type(age))
print(type(score))
대표적인 기본 자료형은 다음과 같다.
| 자료형 | 의미 | 예시 |
|---|---|---|
int | 정수 | 10, -5 |
float | 실수 | 3.14, 85.23 |
str | 문자열 | "python" |
bool | 참/거짓 | True, False |
#으로 작성한다# 주문 금액
order_amount = 35000
주석은 실행되지 않고 코드의 의미를 설명하는 데 사용한다.
변수명이나 함수명처럼 코드에 이름을 붙일 때 사용하는 단어를 식별자(identifier) 라고 한다.
Python 식별자에는 몇 가지 기본 규칙이 있다.
if, for, while, class 같은 예약어를 사용할 수 없다._를 제외한 특수문자는 사용할 수 없다.# 좋은 예
user_name = "kim"
english_score = 92
order_01 = 15000
# 잘못된 예
# 1user = "kim"
# user name = "kim"
# if = 10
여러 단어를 연결할 때는 보통 snake_case 형태가 읽기 좋다.
total_order_amount = 125000
여러 줄의 텍스트를 하나의 문자열로 저장해야 할 때는 """ 또는 '''를 사용할 수 있다.
message = """API 요청이 완료되었습니다.
처리된 데이터는 캐시에 저장됩니다.
다음 요청부터는 캐시를 먼저 확인합니다."""
print(message)
설명문, SQL 문자열, 긴 템플릿 등을 다룰 때 유용하다.
정수와 실수에는 일반적인 산술 연산자를 사용할 수 있다.
a = 26
b = 5
print(a + b) # 31
print(a - b) # 21
print(a * b) # 130
print(a / b) # 5.2
print(a // b) # 5
print(a % b) # 1
print(a ** 2) # 676
특히 %는 조건 처리에서 자주 사용된다.
number = 12
print(number % 2 == 0)
# True
기존 변수에 연산 결과를 다시 저장할 때는 복합 대입 연산자를 사용할 수 있다.
count = 10
count += 5
count -= 2
count *= 2
count /= 4
print(count)
반복문에서 카운터나 누적값을 계산할 때 특히 자주 등장한다.
두 값을 비교한 결과는 True 또는 False가 된다.
score = 85
print(score > 90)
print(score >= 80)
print(score == 85)
print(score != 100)
여기서 =와 ==는 의미가 완전히 다르다.
score = 85 # 대입
score == 85 # 비교
문자열의 + 연산은 숫자 덧셈이 아니라 문자열 연결이다.
frontend = "React"
backend = "FastAPI"
stack = frontend + " + " + backend
print(stack)
# React + FastAPI
문자열에 정수를 곱하면 해당 횟수만큼 반복된다.
print("-" * 30)
print("Python" == "python")
# False
사용자 입력을 비교해야 할 때는 대소문자를 통일한 뒤 비교하는 방법을 자주 사용한다.
command = "START"
if command.lower() == "start":
print("실행")
변수 값을 문자열 안에 넣을 때는 f-string이 편리하다.
user_name = "승준"
request_count = 24
print(f"{user_name}님의 API 요청 수는 {request_count}회입니다.")
숫자의 출력 형식도 지정할 수 있다.
amount = 2345.6789
print(f"결제 금액: {amount:,.2f}원")
# 결제 금액: 2,345.68원
:,는 천 단위 구분 기호를 표시하고 .2f는 소수점 둘째 자리까지 표시한다.
객체 뒤에 .메서드() 형태로 호출하는 함수를 메서드(method) 라고 한다.
문자열에서 자주 사용하는 메서드는 다음과 같다.
text = "Python Data"
print(text.upper())
print(text.lower())
price = "12,500"
price = price.replace(",", "")
print(price)
# 12500
split()log = "2026-10-02,login,success"
parts = log.split(",")
print(parts)
# ['2026-10-02', 'login', 'success']
join()tech_stack = ["Python", "Pandas", "FastAPI"]
result = " / ".join(tech_stack)
print(result)
# Python / Pandas / FastAPI
문자열에는 이외에도 count(), find(), capitalize() 등 다양한 메서드가 있다.
문자열 메서드를 실행했다고 해서 원래 문자열 자체가 변경되는 것은 아니다.
language = "python"
language.upper()
print(language)
# python
변환 결과를 유지하려면 반환값을 다시 저장해야 한다.
language = language.upper()
print(language)
# PYTHON
이러한 특징을 불변(immutable) 이라고 한다.
이 개념은 뒤에서 살펴볼 리스트의 변경 가능(mutable) 특성과 비교하면 더 쉽게 이해할 수 있다.
데이터 분석이나 API 처리에서는 문자열로 들어온 숫자를 실제 숫자로 변환해야 하는 경우가 많다.
price = "15000"
quantity = "3"
total = int(price) * int(quantity)
print(total)
# 45000
대표적인 변환 함수는 다음과 같다.
int("10")
float("10.5")
str(100)
bool(1)
쉼표가 포함된 숫자 문자열은 먼저 정리해야 한다.
price = "123,456"
price = price.replace(",", "")
price = int(price)
print(price * 2)
# 246912
리스트는 여러 값을 하나로 묶어서 관리하는 컨테이너 자료형이다.
scores = [85, 95, 90, 75]
print(scores)
print(len(scores))
대괄호 [] 안에 요소를 쉼표로 구분해 작성한다.
서로 다른 자료형도 하나의 리스트에 넣을 수 있다.
user = [101, "seungjun", True, 92.5]
request_counts = [
[12, 14, 18],
[20, 17, 19],
[25, 22, 30],
]
바깥쪽 리스트의 요소는 내부 리스트 3개이므로 다음 결과는 3이다.
print(len(request_counts))
# 3
이후 데이터를 하나씩 저장할 목적이라면 빈 리스트를 먼저 만들 수 있다.
result = []
또는 다음과 같이 만들 수 있다.
result = list()
range()로 연속된 숫자 만들기연속된 정수를 만들 때는 range()가 편리하다.
numbers = list(range(5))
print(numbers)
# [0, 1, 2, 3, 4]
시작값과 종료값을 지정할 수도 있다.
numbers = list(range(3, 8))
print(numbers)
# [3, 4, 5, 6, 7]
증가 폭도 지정할 수 있다.
numbers = list(range(0, 10, 2))
print(numbers)
# [0, 2, 4, 6, 8]
range()의 종료값은 포함되지 않는다.
리스트의 위치는 0부터 시작한다.
frameworks = ["React", "Vue", "Svelte", "Angular"]
print(frameworks[0])
# React
뒤에서부터 접근할 때는 음수 인덱스를 사용할 수 있다.
print(frameworks[-1])
# Angular
01-1-2여러 요소를 범위로 가져올 때는 슬라이싱을 사용한다.
frameworks = ["React", "Vue", "Svelte", "Angular"]
print(frameworks[1:3])
# ['Vue', 'Svelte']
[시작:끝]에서 끝 인덱스는 포함되지 않는다.
print(frameworks[:2])
print(frameworks[2:])
print(frameworks[:])
리스트는 변경 가능한(mutable) 자료형이다.
numbers = [10, 20, 30, 40]
numbers[1] = 200
print(numbers)
# [10, 200, 30, 40]
슬라이싱한 범위도 한 번에 바꿀 수 있다.
numbers = [0, 1, 2, 3, 4, 5]
numbers[2:4] = [20, 30]
print(numbers)
# [0, 1, 20, 30, 4, 5]
기존 범위의 요소 개수와 새로운 요소 개수가 같을 필요도 없다.
numbers = [0, 1, 2, 3, 4, 5]
numbers[2:5] = [100, 200]
print(numbers)
# [0, 1, 100, 200, 5]
슬라이싱 대입은 특정 범위를 통째로 다른 요소 묶음으로 교체한다고 이해하면 쉽다.
append()는 요소 하나를 맨 뒤에 추가한다skills = ["HTML", "CSS"]
skills.append("JavaScript")
print(skills)
# ['HTML', 'CSS', 'JavaScript']
append()에 리스트를 전달해도 전달한 리스트 전체가 요소 하나로 추가된다.
skills.append(["React", "Next.js"])
print(skills)
# ['HTML', 'CSS', 'JavaScript', ['React', 'Next.js']]
insert()는 특정 위치에 삽입한다skills = ["HTML", "JavaScript"]
skills.insert(1, "CSS")
print(skills)
# ['HTML', 'CSS', 'JavaScript']
기존 값을 덮어쓰는 것이 아니라 해당 위치의 기존 요소를 뒤로 밀고 새 요소를 삽입한다.
+와 extend()는 여러 요소를 이어 붙인다리스트끼리 + 연산을 하면 새로운 리스트가 결합된다.
numbers = [1, 2, 3, 4] + [2]
print(numbers)
# [1, 2, 3, 4, 2]
리스트에 여러 요소를 직접 추가할 때는 extend()를 사용할 수 있다.
skills = ["HTML", "CSS"]
skills.extend(["JavaScript", "React"])
print(skills)
# ['HTML', 'CSS', 'JavaScript', 'React']
차이는 다음처럼 기억하면 쉽다.
append(x) → x 전체를 요소 하나로 추가
extend(xs) → xs 안의 요소들을 각각 추가
위치를 알고 있다면 del을 사용할 수 있다.
numbers = [10, 20, 30, 40]
del numbers[1]
print(numbers)
# [10, 30, 40]
범위를 비어 있는 리스트로 바꾸면 해당 구간을 제거하는 효과가 있다.
numbers = [10, 20, 30, 40, 50]
numbers[2:] = []
print(numbers)
# [10, 20]
리스트 전체를 비우고 새 빈 리스트가 필요하다면 다음처럼 다시 대입할 수도 있다.
numbers = []
count()와 index()scores = [100, 80, 100, 90]
print(scores.count(100))
# 2
print(scores.index(100))
# 0
index()는 찾는 값이 없으면 오류가 발생한다.
remove()와 pop()items = ["A", "B", "C"]
items.remove("B")
print(items)
# ['A', 'C']
pop()은 요소를 제거하면서 그 값을 반환한다.
items = ["A", "B", "C"]
last_item = items.pop()
print(last_item)
print(items)
reverse()와 sort()numbers = [3, 1, 4, 2]
numbers.reverse()
print(numbers)
numbers = [3, 1, 4, 2]
numbers.sort()
print(numbers)
# [1, 2, 3, 4]
내림차순은 다음처럼 지정할 수 있다.
numbers.sort(reverse=True)
문자열과 달리 이러한 리스트 메서드 중 상당수는 리스트 자체를 실제로 변경한다.
튜플은 리스트와 비슷하지만 한 번 생성한 뒤 요소 값을 변경할 수 없다.
position = (120, 250)
괄호를 생략해도 튜플을 만들 수 있다.
position = 120, 250
다음 코드는 튜플이 아니라 정수다.
value = (10)
print(type(value))
# <class 'int'>
요소가 하나인 튜플은 쉼표가 필요하다.
value = (10,)
print(type(value))
# <class 'tuple'>
튜플에서는 주로 count(), index() 같은 조회 메서드를 사용할 수 있다.
집합은 중괄호 {}로 만들며 중복 값을 허용하지 않는다.
user_ids = {101, 102, 102, 103}
print(user_ids)
집합은 원소의 순서가 핵심이 아니므로 리스트처럼 인덱싱이나 슬라이싱을 하지 않는다.
frontend_users = {1, 2, 3, 4}
ai_users = {3, 4, 5, 6}
합집합:
print(frontend_users | ai_users)
print(frontend_users.union(ai_users))
교집합:
print(frontend_users & ai_users)
print(frontend_users.intersection(ai_users))
차집합:
print(frontend_users - ai_users)
print(frontend_users.difference(ai_users))
대칭 차집합:
print(frontend_users ^ ai_users)
print(frontend_users.symmetric_difference(ai_users))
여러 값을 추가할 때는 update()도 사용할 수 있다.
frontend_users.update([7, 8])
딕셔너리는 Key: Value 쌍으로 데이터를 저장한다.
user = {
"name": "seungjun",
"level": "gold",
"score": 92,
}
값은 Key를 이용해 조회한다.
print(user["name"])
# seungjun
in은 기본적으로 Key를 확인한다print("name" in user)
# True
print("seungjun" in user)
# False
딕셔너리 Value 안의 값을 확인할 수도 있다.
profile = {
"skills": ["Python", "Pandas", "React"]
}
print("Pandas" in profile["skills"])
# True
user["score"] = 95
user["role"] = "developer"
이미 존재하는 Key라면 값이 변경되고, 없는 Key라면 새 항목이 추가된다.
del user["level"]
user.keys()
user.values()
user.items()
Key가 없을 가능성이 있다면 get()을 사용할 수 있다.
print(user.get("email", "없음"))
# 없음
[]로 없는 Key에 접근하면 오류가 발생할 수 있지만 get()은 대체 값을 지정할 수 있다는 차이가 있다.
if, elif, else조건에 따라 실행할 코드를 나눌 수 있다.
score = 87
if score >= 90:
grade = "A"
elif score >= 80:
grade = "B"
elif score >= 70:
grade = "C"
else:
grade = "D"
print(grade)
Python 제어문은 콜론 :과 들여쓰기로 코드 블록을 구분한다.
if score >= 80:
print("통과")
들여쓰기는 보통 공백 4칸을 사용한다.
for 문리스트나 튜플, 문자열 같은 여러 값에서 요소를 하나씩 꺼내 처리할 때 for 문을 사용한다.
frameworks = ["React", "Vue", "Svelte"]
for framework in frameworks:
print(framework)
range()와 함께 사용하면 반복 횟수를 만들기 쉽다.
for index in range(5):
print(index)
enumerate()로 인덱스와 값을 함께 받기frameworks = ["React", "Vue", "Svelte"]
for index, framework in enumerate(frameworks):
print(index, framework)
반복 중인 값이 몇 번째 요소인지 함께 필요할 때 유용하다.
반복문으로 새로운 리스트를 만들 때 더 간결한 문법을 사용할 수 있다.
일반 반복문:
numbers = [1, 2, 3, 4, 5]
squares = []
for number in numbers:
squares.append(number ** 2)
리스트 컴프리헨션:
squares = [number ** 2 for number in numbers]
조건도 함께 사용할 수 있다.
even_squares = [
number ** 2
for number in numbers
if number % 2 == 0
]
예를 들어 1부터 9까지 숫자 중 3의 배수만 골라 두 배로 만들면 다음과 같다.
result = [
number * 2
for number in range(1, 10)
if number % 3 == 0
]
print(result)
# [6, 12, 18]
딕셔너리에서 Key와 Value를 함께 반복하려면 items()가 편리하다.
scores = {
"frontend": 85,
"python": 95,
"sql": 90,
}
for key, value in scores.items():
print(f"{key}: {value}")
딕셔너리 컴프리헨션도 사용할 수 있다.
high_scores = {
key: value
for key, value in scores.items()
if value > 90
}
while 문조건이 True인 동안 반복해서 실행한다.
count = 0
while count < 5:
print(count)
count += 1
종료 조건을 제대로 만들지 않으면 무한 반복될 수 있으므로 주의해야 한다.
break와 continuebreak는 반복문을 즉시 종료한다.
while True:
command = input("명령을 입력하세요: ")
if command == "exit":
break
continue는 현재 반복의 남은 코드를 건너뛰고 다음 반복으로 넘어간다.
for number in range(1, 6):
if number == 3:
continue
print(number)
함수는 입력을 받아 특정 작업을 수행하고 필요하면 결과를 반환하는 재사용 가능한 코드 단위다.
def calculate_total(price, quantity):
return price * quantity
total = calculate_total(12000, 3)
print(total)
# 36000
함수는 def로 정의한다.
입력값이 필요하지 않은 함수도 만들 수 있다.
def print_separator():
print("-" * 30)
print_separator()
입력이 필요하면 매개변수를 선언한다.
def greet(name):
print(f"{name}님 안녕하세요.")
매개변수에 기본값을 지정할 수 있다.
def create_message(name="사용자"):
return f"{name}님, 처리가 완료되었습니다."
print(create_message("승준"))
print(create_message())
매개변수의 순서에 맞게 값을 전달할 수 있다.
def create_log(level, message="완료"):
return f"[{level}] {message}"
print(create_log("INFO", "서버 시작"))
매개변수 이름을 직접 지정하면 순서를 바꿀 수도 있다.
print(create_log(message="서버 시작", level="INFO"))
return과 None함수의 결과를 외부로 돌려주려면 return을 사용한다.
def add(a, b):
return a + b
반환값이 없는 함수의 실행 결과를 변수에 저장하면 None이 된다.
def show_message():
print("완료")
result = show_message()
print(result)
# None
print()와 return은 역할이 다르다.
print() : 화면에 보여준다.return : 함수 밖으로 값을 전달한다.함수에서 여러 값을 반환할 수도 있다.
def calculate_stats(numbers):
total = sum(numbers)
average = total / len(numbers)
return total, average
total, average = calculate_stats([10, 20, 30])
print(total)
print(average)
여러 반환값은 튜플 형태로 묶여 전달된다.
지금까지의 문법을 실제 데이터 처리 형태로 연결해보자.
logs = [
{"user_id": 101, "event": "click", "count": 5},
{"user_id": 102, "event": "view", "count": 12},
{"user_id": 103, "event": "click", "count": 8},
{"user_id": 104, "event": "click", "count": 2},
]
클릭 이벤트이면서 횟수가 5 이상인 데이터만 추출하는 함수를 만들어보자.
def filter_active_clicks(logs, minimum_count=5):
result = []
for log in logs:
is_click = log["event"] == "click"
is_active = log["count"] >= minimum_count
if is_click and is_active:
result.append(log)
return result
active_clicks = filter_active_clicks(logs)
print(active_clicks)
여기에는 Python 데이터 처리의 핵심 문법이 자연스럽게 연결되어 있다.
리스트 → 여러 로그 저장
딕셔너리 → 로그 한 건의 속성 표현
for → 로그 반복 처리
if → 조건 판단
append() → 조건을 통과한 결과 저장
함수 → 처리 로직 재사용
text = "python"
text.upper()
print(text)
# python
numbers = [3, 1, 2]
numbers.sort()
print(numbers)
# [1, 2, 3]
문자열은 불변이고 리스트는 변경 가능하다는 차이 때문이다.
append()와 extend()items = [1, 2]
items.append([3, 4])
print(items)
# [1, 2, [3, 4]]
items = [1, 2]
items.extend([3, 4])
print(items)
# [1, 2, 3, 4]
a = [1, 2, 3, 4] + [2]
print(a)
# [1, 2, 3, 4, 2]
items = [0, 1, 2, 3, 4]
print(items[1:4])
# [1, 2, 3]
value = (10,)
in은 Key 기준이다user = {"name": "승준"}
print("name" in user)
# True
print("승준" in user)
# False
type()으로 자료형을 확인할 수 있다.+=, -=, *=, /= 같은 복합 대입 연산자도 자주 사용한다.upper(), lower(), replace(), split(), join() 등으로 가공할 수 있지만 원본 자체는 변경되지 않는 불변 자료형이다.append(), insert(), extend() 등을 사용한다.Key: Value 구조로 데이터를 표현하며 items(), get() 등을 활용하면 조회와 반복 처리가 편리하다.if는 조건 처리, for와 while은 반복 처리에 사용하고 enumerate(), 컴프리헨션, break, continue로 반복 로직을 확장할 수 있다.def로 묶어 재사용하며 매개변수, 기본값, 키워드 인자, return을 이용해 입출력을 제어한다.