Python 데이터 분석 실무 완전 정복

Python을 활용한 실무 데이터 분석 기술을 마스터합니다. 기본 문법부터 NumPy 배열 연산, Pandas 데이터 조작, Matplotlib/Seaborn 시각화, 실무 데이터 파이프라인 구축까지 전체 프로세스를 학습합니다. Leetcode 알고리즘 문제 해결 능력과 OOP를 활용한 코드 구조화 방법도 함께 다룹니다.

Data Science,Python,Pandas,NumPy,Visualization중급
16시간
16개 항목
학습 진행률0 / 16 (0%)

학습 항목

1. Data Science
초급
Python 기초 문법 완벽 가이드
퀴즈튜토리얼
2. Data Science
초급
객체지향 프로그래밍 완벽 가이드
퀴즈튜토리얼
3. Data Science
초급
Python 파일 입출력 및 예외 처리 완벽 가이드
퀴즈튜토리얼
4. Data Science
초급
NumPy 배열 생성 및 인덱싱 완벽 가이드
퀴즈튜토리얼
5. Data Science
초급
NumPy 수학 연산 및 통계 함수 완벽 가이드
퀴즈튜토리얼
6. Data Science
초급
NumPy 실전 활용 완벽 가이드 - 행렬 연산과 성능 최적화
퀴즈튜토리얼
7. Data Science
초급
Pandas Series와 DataFrame 완벽 가이드
퀴즈튜토리얼
8. Data Science
초급
Pandas 데이터 전처리 마스터
퀴즈튜토리얼
9. Data Science
초급
GroupBy 및 Aggregation 활용 완벽 가이드
퀴즈튜토리얼
10. Data Science
초급
Pandas 데이터 결합 완벽 가이드
퀴즈튜토리얼
11. Data Science
초급
Pandas 시계열 데이터 처리 완벽 가이드
퀴즈튜토리얼
12. Data Science
초급
Matplotlib 기초부터 커스터마이징까지 완벽 가이드
퀴즈튜토리얼
13. Data Science
초급
Seaborn 고급 시각화 완벽 가이드
퀴즈튜토리얼
14. Data Science
초급
실무 시각화 완벽 가이드 - 데이터로 인사이트 도출하기
퀴즈튜토리얼
15. Data Science
초급
Leetcode 알고리즘 문제 해결 전략 완벽 가이드
퀴즈튜토리얼
16. Data Science
초급
실전 프로젝트 데이터 분석 파이프라인 구축 완벽 가이드
퀴즈튜토리얼
1 / 16

이미지 로딩 중...

Python 기초 문법 완벽 가이드 - 슬라이드 1/9

Python 기초 문법 완벽 가이드

Python의 기초 문법과 데이터 구조를 초급 개발자를 위해 쉽고 친근하게 설명합니다. 변수부터 리스트, 딕셔너리, 함수까지 실무에서 바로 활용할 수 있는 핵심 개념들을 다룹니다.


목차

  1. 변수와 데이터 타입 - 데이터를 담는 상자
  2. 리스트 - 여러 개의 데이터를 한 번에
  3. 딕셔너리 - 이름표가 붙은 데이터 저장소
  4. 함수 - 반복되는 작업을 한 번에
  5. 조건문 - 상황에 따라 다르게 행동하기
  6. 반복문 - 같은 작업을 여러 번
  7. 문자열 다루기 - 텍스트 마법사
  8. 예외 처리 - 에러를 우아하게 다루기

1. 변수와 데이터 타입 - 데이터를 담는 상자

시작하며

여러분이 쇼핑몰 웹사이트를 만든다고 상상해보세요. 사용자의 이름, 나이, 구매 금액을 저장해야 하는데 어디에 어떻게 보관해야 할지 막막하셨나요?

이런 문제는 프로그래밍을 처음 시작하는 모든 분들이 겪는 첫 번째 관문입니다. 데이터를 어떻게 저장하고 관리할지 모르면 아무것도 만들 수 없습니다.

바로 이럴 때 필요한 것이 변수와 데이터 타입입니다. 마치 서로 다른 물건을 담는 다양한 상자처럼, 각각의 데이터를 적절한 형태로 보관할 수 있게 해줍니다.

개요

간단히 말해서, 변수는 데이터를 담는 상자이고, 데이터 타입은 그 상자에 어떤 종류의 물건을 담을지 정하는 것입니다. 실무에서 여러분이 사용자 정보를 처리하거나, 계산을 하거나, 텍스트를 다룰 때 변수가 필요합니다.

예를 들어, 온라인 쇼핑몰에서 사용자가 장바구니에 담은 상품의 총 가격을 계산할 때 매우 유용합니다. 기존에는 계산기로 하나하나 계산했다면, 이제는 변수에 값을 저장하고 자동으로 계산할 수 있습니다.

Python의 주요 데이터 타입은 정수(int), 실수(float), 문자열(str), 불린(bool)이 있습니다. 각각 숫자, 소수점 숫자, 글자, 참/거짓을 나타내며, 이들을 올바르게 사용하면 프로그램이 원하는 대로 정확하게 동작합니다.

코드 예제

# 정수형 변수 - 사용자의 나이 저장
age = 25

# 실수형 변수 - 상품 가격 저장
price = 29.99

# 문자열 변수 - 사용자 이름 저장
username = "김철수"

# 불린 변수 - 로그인 상태 확인
is_logged_in = True

# 변수 출력하기
print(f"{username}님의 나이는 {age}세이고, 상품 가격은 {price}원입니다.")
print(f"로그인 상태: {is_logged_in}")

설명

이것이 하는 일: 변수를 선언하고 각각의 데이터 타입에 맞는 값을 저장한 후, 화면에 출력합니다. 첫 번째로, age = 25는 age라는 이름의 상자를 만들고 그 안에 숫자 25를 넣습니다.

등호(=)는 오른쪽 값을 왼쪽 변수에 저장하라는 의미입니다. Python은 자동으로 25가 정수라는 것을 알아챕니다.

그 다음으로, price = 29.99처럼 소수점이 있는 숫자를 저장하면 Python은 이를 실수(float) 타입으로 인식합니다. 마찬가지로 따옴표로 감싸진 텍스트는 문자열(str)로, True/False는 불린(bool)으로 자동 인식됩니다.

마지막으로, print(f"{username}님의...")는 f-string이라는 기능을 사용하여 변수의 값을 문장 안에 자연스럽게 삽입합니다. 중괄호 {} 안에 변수 이름을 넣으면 그 자리에 변수의 값이 들어갑니다.

여러분이 이 코드를 사용하면 사용자 정보를 체계적으로 관리하고, 필요할 때마다 꺼내서 사용할 수 있습니다. 웹사이트, 앱, 데이터 분석 등 모든 프로그래밍의 기초가 되며, 데이터를 안전하게 보관하고 처리할 수 있습니다.

실전 팁

💡 변수 이름은 의미있게 지으세요. x = 25보다 user_age = 25가 나중에 코드를 읽을 때 훨씬 이해하기 쉽습니다.

💡 Python은 변수 타입을 자동으로 인식하지만, type(age)로 확인할 수 있습니다. 예상과 다른 타입일 때 버그가 생기므로 확인하는 습관을 들이세요.

💡 문자열을 다룰 때는 작은따옴표('')와 큰따옴표("")를 일관되게 사용하세요. 둘 다 가능하지만 한 프로젝트에서는 하나로 통일하는 것이 좋습니다.

💡 변수 이름에는 숫자로 시작할 수 없고, 공백이나 특수문자를 사용할 수 없습니다. 대신 언더스코어(_)를 사용하세요. 예: user_name, total_price


2. 리스트 - 여러 개의 데이터를 한 번에

시작하며

여러분이 학생 10명의 시험 점수를 저장해야 한다고 상상해보세요. 변수를 score1 = 85, score2 = 90, score3 = 78...

이렇게 10개나 만들어야 할까요? 이런 방식은 매우 비효율적입니다.

변수가 많아질수록 관리가 어려워지고, 평균을 구하거나 최고 점수를 찾는 것도 복잡해집니다. 만약 학생이 100명이라면 변수를 100개나 만들어야 할까요?

바로 이럴 때 필요한 것이 리스트입니다. 하나의 상자에 여러 개의 물건을 순서대로 담듯이, 리스트는 여러 개의 데이터를 하나의 이름으로 관리할 수 있게 해줍니다.

개요

간단히 말해서, 리스트는 여러 개의 값을 순서대로 저장하는 데이터 구조입니다. 실무에서 여러분이 여러 사용자의 정보를 관리하거나, 상품 목록을 보여주거나, 시간별 온도 데이터를 분석할 때 리스트가 필요합니다.

예를 들어, 쇼핑몰에서 장바구니에 담긴 여러 상품을 관리할 때 매우 유용합니다. 기존에는 개별 변수를 여러 개 만들어야 했다면, 이제는 하나의 리스트로 모든 데이터를 관리할 수 있습니다.

리스트의 핵심 특징은 첫째, 대괄호 []로 만들고, 둘째, 순서가 있어서 인덱스로 접근 가능하며, 셋째, 값을 추가하거나 삭제할 수 있다는 점입니다. 이러한 특징들 덕분에 데이터를 동적으로 관리하고 반복 작업을 쉽게 수행할 수 있습니다.

코드 예제

# 학생들의 시험 점수를 리스트로 저장
scores = [85, 90, 78, 92, 88]

# 첫 번째 점수 가져오기 (인덱스는 0부터 시작)
first_score = scores[0]
print(f"첫 번째 학생 점수: {first_score}")

# 새로운 점수 추가
scores.append(95)

# 평균 계산
average = sum(scores) / len(scores)
print(f"평균 점수: {average:.2f}")

# 모든 점수 출력
for score in scores:
    print(f"점수: {score}")

설명

이것이 하는 일: 여러 학생의 점수를 하나의 리스트에 저장하고, 개별 점수에 접근하거나 새로운 점수를 추가하며, 평균을 계산합니다. 첫 번째로, scores = [85, 90, 78, 92, 88]는 5개의 점수를 담은 리스트를 만듭니다.

대괄호 안에 쉼표로 구분된 값들이 순서대로 저장됩니다. 이렇게 하면 하나의 변수 이름으로 여러 데이터를 관리할 수 있습니다.

그 다음으로, scores[0]은 리스트의 첫 번째 값을 가져옵니다. 중요한 점은 Python에서 인덱스가 0부터 시작한다는 것입니다.

따라서 첫 번째는 0, 두 번째는 1, 세 번째는 2가 됩니다. scores.append(95)는 리스트의 맨 끝에 새로운 값 95를 추가합니다.

세 번째 단계에서, sum(scores)는 리스트의 모든 값을 더하고, len(scores)는 리스트의 길이(항목 개수)를 반환합니다. 이 둘을 나누면 평균이 계산됩니다.

:.2f는 소수점 둘째 자리까지만 표시하라는 의미입니다. 마지막으로, for score in scores: 반복문은 리스트의 모든 항목을 하나씩 꺼내서 처리합니다.

이렇게 하면 100개의 점수가 있어도 같은 코드로 모두 처리할 수 있습니다. 여러분이 이 코드를 사용하면 데이터가 아무리 많아도 체계적으로 관리할 수 있습니다.

학생 관리 시스템, 상품 목록, 주식 가격 데이터 등 순서가 있는 모든 데이터를 효율적으로 다룰 수 있으며, 코드도 훨씬 간결해집니다.

실전 팁

💡 리스트의 마지막 항목은 scores[-1]로 접근할 수 있습니다. -1은 뒤에서 첫 번째, -2는 뒤에서 두 번째를 의미합니다.

💡 리스트 슬라이싱을 활용하세요. scores[1:4]는 인덱스 1부터 3까지(4는 포함 안 됨)의 항목을 가져옵니다. 처음부터는 [:3], 끝까지는 [2:]로 표현합니다.

💡 리스트가 비어있는지 확인할 때는 if not scores:를 사용하세요. 빈 리스트는 False로 평가되어 에러를 방지할 수 있습니다.

💡 리스트를 복사할 때는 new_list = scores[:] 또는 new_list = scores.copy()를 사용하세요. new_list = scores는 참조만 복사하므로 한쪽을 수정하면 다른쪽도 바뀝니다.

💡 in 키워드로 특정 값이 리스트에 있는지 확인할 수 있습니다. 예: if 90 in scores:는 90점이 있으면 True를 반환합니다.


3. 딕셔너리 - 이름표가 붙은 데이터 저장소

시작하며

여러분이 사용자 정보를 저장한다고 상상해보세요. 이름, 나이, 이메일, 전화번호가 있는데, 리스트로 user = ["김철수", 25, "kim@email.com", "010-1234-5678"]처럼 저장했다면, 나중에 user[2]가 이메일인지 전화번호인지 헷갈리지 않으셨나요?

이런 문제는 데이터가 많아질수록 심각해집니다. 인덱스 숫자만으로는 각 데이터가 무엇을 의미하는지 알 수 없고, 실수로 잘못된 위치의 데이터를 가져오면 버그가 발생합니다.

바로 이럴 때 필요한 것이 딕셔너리입니다. 마치 사전에서 단어를 찾듯이, 각 데이터에 의미있는 이름표를 붙여서 쉽게 찾을 수 있게 해줍니다.

개요

간단히 말해서, 딕셔너리는 키(key)와 값(value)의 쌍으로 데이터를 저장하는 구조입니다. 실무에서 여러분이 JSON 데이터를 다루거나, 설정 파일을 읽거나, 데이터베이스에서 가져온 정보를 처리할 때 딕셔너리가 필요합니다.

예를 들어, API에서 받은 사용자 정보를 파싱할 때 매우 유용합니다. 기존에는 순서로만 데이터에 접근했다면, 이제는 의미있는 이름으로 직접 접근할 수 있습니다.

딕셔너리의 핵심 특징은 첫째, 중괄호 {}로 만들고, 둘째, 키로 값에 빠르게 접근 가능하며, 셋째, 순서가 없지만(Python 3.7+부터는 입력 순서 유지) 키는 중복될 수 없다는 점입니다. 이러한 특징들 덕분에 복잡한 데이터 구조를 직관적으로 표현하고 관리할 수 있습니다.

코드 예제

# 사용자 정보를 딕셔너리로 저장
user = {
    "name": "김철수",
    "age": 25,
    "email": "kim@email.com",
    "phone": "010-1234-5678"
}

# 키로 값 가져오기
print(f"이름: {user['name']}")
print(f"나이: {user['age']}")

# 새로운 키-값 추가
user["address"] = "서울시 강남구"

# 안전하게 값 가져오기 (키가 없으면 기본값 반환)
job = user.get("job", "미등록")
print(f"직업: {job}")

# 모든 키-값 쌍 출력
for key, value in user.items():
    print(f"{key}: {value}")

설명

이것이 하는 일: 사용자 정보를 키-값 쌍으로 저장하고, 키를 사용해 특정 정보를 가져오거나 새로운 정보를 추가합니다. 첫 번째로, 딕셔너리는 중괄호 {} 안에 "키": 값 형식으로 데이터를 저장합니다.

콜론(:)으로 키와 값을 연결하고, 쉼표(,)로 각 쌍을 구분합니다. 키는 반드시 따옴표로 감싸야 하며, 값은 어떤 타입이든 가능합니다.

이렇게 하면 user['name']처럼 의미있는 이름으로 데이터에 접근할 수 있습니다. 그 다음으로, 대괄호 안에 키를 넣으면 해당 값을 가져옵니다.

user['name']은 "김철수"를 반환합니다. 새로운 데이터를 추가할 때도 같은 방식으로 user["address"] = "서울시 강남구"처럼 작성하면 됩니다.

이미 존재하는 키에 값을 할당하면 기존 값이 업데이트됩니다. 세 번째로, user.get("job", "미등록")은 더 안전한 방법입니다.

만약 "job" 키가 딕셔너리에 없으면 에러 대신 기본값인 "미등록"을 반환합니다. 이는 존재하지 않을 수 있는 데이터를 다룰 때 프로그램이 중단되는 것을 방지합니다.

마지막으로, user.items()는 모든 키-값 쌍을 튜플 형태로 반환하여 반복문으로 처리할 수 있게 합니다. for key, value in 구문은 각 쌍을 key와 value 변수에 분리해서 할당하므로 모든 데이터를 순회하며 출력할 수 있습니다.

여러분이 이 코드를 사용하면 복잡한 데이터를 체계적으로 관리할 수 있습니다. 웹 API 응답 처리, 설정 파일 관리, 데이터베이스 레코드 다루기 등에서 코드 가독성이 크게 향상되고, 유지보수가 쉬워집니다.

실전 팁

💡 키가 존재하는지 확인할 때는 if "email" in user:를 사용하세요. 에러 없이 안전하게 확인할 수 있습니다.

💡 딕셔너리의 모든 키만 가져오려면 user.keys(), 모든 값만 가져오려면 user.values()를 사용하세요. 리스트로 변환하려면 list(user.keys())처럼 작성합니다.

💡 여러 딕셔너리를 합칠 때는 {**dict1, **dict2} 또는 dict1.update(dict2)를 사용하세요. 중복 키는 나중 것으로 덮어씌워집니다.

💡 딕셔너리는 JSON 형식과 거의 동일하므로 import json으로 쉽게 변환할 수 있습니다. json.dumps(user)는 딕셔너리를 JSON 문자열로 바꿉니다.

💡 중첩 딕셔너리도 가능합니다. 예: user["address"] = {"city": "서울", "district": "강남구"}처럼 값에 또 다른 딕셔너리를 넣을 수 있습니다.


4. 함수 - 반복되는 작업을 한 번에

시작하며

여러분이 쇼핑몰을 만들고 있는데, 상품 가격에 세금 10%를 더하는 계산을 10군데에서 반복해야 한다고 상상해보세요. price * 1.1을 매번 복사-붙여넣기 하고 계시나요?

이런 방식은 매우 위험합니다. 나중에 세금이 12%로 변경되면 10곳을 모두 찾아서 수정해야 하고, 하나라도 놓치면 버그가 발생합니다.

코드도 지저분하고 관리가 어려워집니다. 바로 이럴 때 필요한 것이 함수입니다.

마치 믹서기에 재료를 넣으면 자동으로 갈아주듯이, 함수는 반복되는 작업을 하나의 이름으로 묶어서 재사용할 수 있게 해줍니다.

개요

간단히 말해서, 함수는 특정 작업을 수행하는 코드 묶음에 이름을 붙인 것입니다. 실무에서 여러분이 같은 계산을 여러 번 하거나, 복잡한 로직을 재사용하거나, 코드를 모듈화해서 관리할 때 함수가 필요합니다.

예를 들어, 이메일 유효성 검사, 비밀번호 암호화, 날짜 형식 변환 같은 작업을 함수로 만들면 매우 유용합니다. 기존에는 같은 코드를 복사-붙여넣기 했다면, 이제는 함수 하나만 수정하면 모든 곳에 적용됩니다.

함수의 핵심 특징은 첫째, def 키워드로 정의하고, 둘째, 입력값(매개변수)을 받아 처리할 수 있으며, 셋째, return으로 결과를 반환할 수 있다는 점입니다. 이러한 특징들 덕분에 코드의 중복을 제거하고, 가독성을 높이며, 테스트와 유지보수가 쉬워집니다.

코드 예제

# 세금을 포함한 가격을 계산하는 함수
def calculate_price_with_tax(price, tax_rate=0.1):
    """
    상품 가격에 세금을 더한 최종 가격을 계산합니다.

    price: 원래 가격
    tax_rate: 세율 (기본값 10%)
    """
    total_price = price * (1 + tax_rate)
    return total_price

# 함수 사용하기
product_price = 10000
final_price = calculate_price_with_tax(product_price)
print(f"최종 가격: {final_price}원")

# 세율을 다르게 적용하기
luxury_price = calculate_price_with_tax(50000, 0.2)
print(f"고급 상품 가격: {luxury_price}원")

설명

이것이 하는 일: 상품 가격과 세율을 입력받아 세금이 포함된 최종 가격을 계산하고 반환합니다. 첫 번째로, def calculate_price_with_tax(price, tax_rate=0.1):는 함수를 정의합니다.

def 키워드 다음에 함수 이름을 쓰고, 괄호 안에 매개변수를 나열합니다. tax_rate=0.1은 기본값을 의미하며, 이 값을 생략하고 함수를 호출하면 자동으로 0.1이 사용됩니다.

콜론(:) 다음 줄부터 들여쓰기된 코드가 함수의 본문입니다. 그 다음으로, 함수 안에서 total_price = price * (1 + tax_rate)처럼 계산을 수행합니다.

이 계산 로직은 함수 내부에만 존재하므로 외부에서는 복잡한 계산 과정을 몰라도 됩니다. 세 개의 따옴표로 감싼 부분은 docstring이라고 하며, 함수의 설명을 작성하는 곳입니다.

세 번째로, return total_price는 계산된 값을 함수 밖으로 돌려줍니다. 함수를 호출한 곳에서 final_price = calculate_price_with_tax(10000)처럼 작성하면 반환된 값이 final_price 변수에 저장됩니다.

return이 없으면 함수는 None을 반환합니다. 마지막으로, 함수는 필요할 때마다 호출할 수 있습니다.

calculate_price_with_tax(50000, 0.2)처럼 다른 값으로 호출하면 같은 로직이 새로운 입력값으로 실행됩니다. 나중에 세율 계산 방식이 바뀌어도 함수 하나만 수정하면 모든 곳에 적용됩니다.

여러분이 이 코드를 사용하면 코드 중복을 제거하고 유지보수가 쉬워집니다. 버그를 찾기도 쉽고, 각 함수를 개별적으로 테스트할 수 있으며, 팀 프로젝트에서 다른 개발자가 여러분의 코드를 이해하기도 쉬워집니다.

실전 팁

💡 함수 이름은 동사로 시작하는 것이 좋습니다. calculate_, get_, validate_, send_ 같은 접두사를 사용하면 함수가 무엇을 하는지 명확해집니다.

💡 하나의 함수는 하나의 일만 해야 합니다. 함수가 너무 길어지면(보통 20줄 이상) 더 작은 함수들로 쪼개는 것을 고려하세요.

💡 매개변수가 3개 이상이면 딕셔너리나 클래스를 사용하는 것이 좋습니다. 예: def create_user(name, age, email, phone, address):보다 def create_user(user_info):가 낫습니다.

💡 타입 힌트를 사용하면 코드가 더 명확해집니다. 예: def calculate_price_with_tax(price: float, tax_rate: float = 0.1) -> float:

💡 함수는 부작용(side effect)을 최소화하세요. 외부 변수를 수정하기보다는 값을 받아서 처리하고 결과를 반환하는 순수 함수가 테스트하기 쉽습니다.


5. 조건문 - 상황에 따라 다르게 행동하기

시작하며

여러분이 로그인 시스템을 만들고 있는데, 비밀번호가 맞으면 "로그인 성공", 틀리면 "비밀번호 오류"를 보여줘야 한다고 상상해보세요. 모든 경우에 같은 메시지를 보여줄 수는 없겠죠?

이런 문제는 프로그램이 상황을 판단하고 다르게 행동해야 할 때 발생합니다. 나이에 따라 다른 콘텐츠를 보여주거나, 재고에 따라 주문을 받거나 거부하는 등 실무에서는 이런 판단이 필수입니다.

바로 이럴 때 필요한 것이 조건문입니다. 마치 길을 걷다가 갈림길에서 표지판을 보고 방향을 정하듯이, 조건문은 프로그램이 상황을 판단하고 다른 행동을 하게 만듭니다.

개요

간단히 말해서, 조건문은 특정 조건이 참인지 거짓인지에 따라 다른 코드를 실행하는 구조입니다. 실무에서 여러분이 사용자 권한을 확인하거나, 입력값을 검증하거나, 비즈니스 로직을 구현할 때 조건문이 필요합니다.

예를 들어, 쇼핑몰에서 재고가 있을 때만 주문을 받거나, VIP 회원에게 할인을 적용할 때 매우 유용합니다. 기존에는 모든 경우를 똑같이 처리했다면, 이제는 상황에 맞게 다르게 대응할 수 있습니다.

조건문의 핵심 특징은 첫째, if, elif, else 키워드를 사용하고, 둘째, 조건식은 True 또는 False로 평가되며, 셋째, 들여쓰기로 조건에 따라 실행할 코드를 구분한다는 점입니다. 이러한 특징들 덕분에 프로그램이 지능적으로 판단하고 동작할 수 있습니다.

코드 예제

# 사용자 나이에 따른 콘텐츠 접근 제어
age = 20
has_permission = True

# 조건에 따라 다른 메시지 출력
if age < 13:
    print("어린이용 콘텐츠만 이용 가능합니다.")
elif age < 19:
    print("청소년용 콘텐츠까지 이용 가능합니다.")
else:
    if has_permission:
        print("모든 콘텐츠를 이용할 수 있습니다.")
    else:
        print("권한이 필요합니다.")

# 간단한 조건문
is_member = True
discount = 0.1 if is_member else 0
print(f"할인율: {discount * 100}%")

설명

이것이 하는 일: 사용자의 나이와 권한을 확인하여 적절한 메시지를 보여주고, 회원 여부에 따라 할인율을 결정합니다. 첫 번째로, if age < 13:은 나이가 13세 미만인지 검사합니다.

조건식 age < 13이 True면 들여쓰기된 코드가 실행되고, False면 건너뜁니다. Python은 비교 연산자 <, >, <=, >=, ==, !=를 사용하여 조건을 검사합니다.

콜론(:) 다음 줄부터 들여쓰기된 부분이 조건이 참일 때 실행되는 코드입니다. 그 다음으로, elif age < 19:는 첫 번째 조건이 거짓일 때만 검사됩니다.

"else if"의 줄임말로, 여러 조건을 순차적으로 검사할 수 있게 합니다. 위에서 아래로 순서대로 검사하며, 하나라도 참이면 해당 블록만 실행하고 나머지는 건너뜁니다.

세 번째로, else:는 모든 조건이 거짓일 때 실행되는 기본 케이스입니다. else 안에 또 다른 if문을 중첩할 수 있으며, 이를 통해 복잡한 조건 로직을 구현할 수 있습니다.

if has_permission: 같은 불린 변수는 == True 없이 바로 사용할 수 있습니다. 마지막으로, discount = 0.1 if is_member else 0은 삼항 연산자(ternary operator)라고 하며, 간단한 조건문을 한 줄로 작성할 때 사용합니다.

is_member가 참이면 0.1이, 거짓이면 0이 discount에 할당됩니다. 여러분이 이 코드를 사용하면 프로그램이 상황을 판단하고 적절하게 대응할 수 있습니다.

사용자 경험을 개인화하고, 에러를 방지하며, 비즈니스 규칙을 정확하게 구현할 수 있습니다. 로그인 시스템, 권한 관리, 유효성 검사 등 거의 모든 프로그램에서 필수적입니다.

실전 팁

💡 복잡한 조건은 괄호로 묶어서 명확하게 만드세요. 예: if (age >= 19 and has_permission) or is_admin:

💡 and, or, not 논리 연산자를 활용하세요. if age >= 19 and age < 65:보다 if 19 <= age < 65:가 더 파이썬스럽습니다.

💡 빈 리스트, 빈 문자열, 0, None은 모두 False로 평가됩니다. 따라서 if not user_list:처럼 간단하게 검사할 수 있습니다.

💡 너무 많은 elif는 딕셔너리나 switch-case 패턴으로 대체하세요. Python 3.10+에서는 match-case 문을 사용할 수 있습니다.

💡 조건문 안에서 변수를 할당할 때는 왈러스 연산자 :=를 사용할 수 있습니다. 예: if (n := len(data)) > 10:


6. 반복문 - 같은 작업을 여러 번

시작하며

여러분이 100명의 학생에게 합격 여부를 알려주는 메시지를 보내야 한다고 상상해보세요. print 문을 100번 복사-붙여넣기 하실 건가요?

이런 방식은 비현실적입니다. 코드가 엄청나게 길어지고, 메시지 내용을 바꾸려면 100곳을 모두 수정해야 합니다.

학생이 1000명이라면 어떻게 하시겠습니까? 바로 이럴 때 필요한 것이 반복문입니다.

마치 세탁기가 설정한 횟수만큼 자동으로 헹구기를 반복하듯이, 반복문은 같은 작업을 원하는 만큼 자동으로 반복해줍니다.

개요

간단히 말해서, 반복문은 같은 코드를 여러 번 실행하는 구조입니다. 실무에서 여러분이 리스트의 모든 항목을 처리하거나, 파일의 모든 줄을 읽거나, 특정 조건이 만족될 때까지 계속 시도할 때 반복문이 필요합니다.

예를 들어, 쇼핑몰에서 모든 상품에 할인을 적용하거나, 모든 주문을 처리할 때 매우 유용합니다. 기존에는 같은 코드를 수동으로 반복 작성했다면, 이제는 몇 줄의 반복문으로 모든 작업을 자동화할 수 있습니다.

반복문의 핵심 특징은 첫째, for는 시퀀스의 각 항목을 순회하고, 둘째, while은 조건이 참인 동안 계속 실행되며, 셋째, breakcontinue로 반복을 제어할 수 있다는 점입니다. 이러한 특징들 덕분에 대량의 데이터를 효율적으로 처리하고 자동화할 수 있습니다.

코드 예제

# for 반복문 - 리스트의 모든 항목 처리
students = ["김철수", "이영희", "박민수", "정수진"]

for student in students:
    print(f"{student}님 합격을 축하합니다!")

# range를 사용한 숫자 반복
for i in range(1, 6):
    print(f"{i}번째 시도")

# while 반복문 - 조건이 참인 동안 실행
count = 0
while count < 3:
    print(f"카운트: {count}")
    count += 1

# break와 continue 사용
for num in range(10):
    if num == 5:
        break  # 5에서 반복 중단
    if num % 2 == 0:
        continue  # 짝수는 건너뛰기
    print(f"홀수: {num}")

설명

이것이 하는 일: 리스트의 각 항목을 순회하며 처리하고, 특정 범위의 숫자를 반복하며, 조건에 따라 반복을 제어합니다. 첫 번째로, for student in students:는 리스트의 각 항목을 하나씩 꺼내서 student 변수에 할당하고, 들여쓰기된 코드를 실행합니다.

첫 번째 반복에서는 student가 "김철수"가 되고, 두 번째 반복에서는 "이영희"가 됩니다. 리스트가 끝날 때까지 자동으로 반복됩니다.

그 다음으로, range(1, 6)은 1부터 5까지의 숫자를 생성합니다(6은 포함 안 됨). for i in range(1, 6):은 i가 1, 2, 3, 4, 5가 되면서 5번 반복됩니다.

range(5)처럼 인자를 하나만 주면 0부터 4까지가 되고, range(0, 10, 2)처럼 세 번째 인자는 증가폭을 의미합니다. 세 번째로, while count < 3:은 조건이 참인 동안 계속 실행됩니다.

반복문 안에서 count += 1로 count를 증가시켜야 무한 루프를 방지할 수 있습니다. while은 반복 횟수를 모를 때 유용하며, 예를 들어 사용자 입력이 올바를 때까지 계속 물어볼 때 사용합니다.

마지막으로, break는 반복문을 즉시 종료하고, continue는 현재 반복만 건너뛰고 다음 반복을 계속합니다. if num == 5: break는 num이 5가 되면 반복을 중단하고, if num % 2 == 0: continue는 짝수일 때 print를 건너뛰므로 홀수만 출력됩니다.

여러분이 이 코드를 사용하면 반복 작업을 자동화하고 코드를 대폭 줄일 수 있습니다. 데이터 처리, 파일 읽기, 웹 스크래핑, 배치 작업 등 대부분의 실무 작업은 반복문 없이 불가능합니다.

특히 데이터 분석에서는 수천, 수만 개의 데이터를 처리할 때 필수적입니다.

실전 팁

💡 리스트를 반복하면서 인덱스도 필요하면 enumerate()를 사용하세요. 예: for i, student in enumerate(students):

💡 두 개의 리스트를 동시에 순회하려면 zip()을 사용하세요. 예: for name, score in zip(names, scores):

💡 리스트 컴프리헨션을 활용하면 한 줄로 새로운 리스트를 만들 수 있습니다. 예: squares = [x**2 for x in range(10)]

💡 무한 루프는 while True:로 만들고 내부에서 break로 빠져나옵니다. 서버 프로그램이나 게임 루프에서 자주 사용됩니다.

💡 반복문의 else 절은 잘 알려지지 않았지만 유용합니다. for ... else:에서 else는 break 없이 정상 종료됐을 때만 실행됩니다.


7. 문자열 다루기 - 텍스트 마법사

시작하며

여러분이 사용자가 입력한 이메일 주소에서 도메인 부분만 추출해야 한다고 상상해보세요. "user@example.com"에서 "example.com"만 가져오려면 어떻게 해야 할까요?

이런 문제는 실무에서 정말 자주 발생합니다. 문자열을 자르고, 합치고, 검색하고, 변환하는 작업은 웹 개발, 데이터 분석, 자동화 스크립트에서 필수적입니다.

문자열을 제대로 다루지 못하면 사용자 입력을 처리하거나 데이터를 정제할 수 없습니다. 바로 이럴 때 필요한 것이 Python의 강력한 문자열 메서드들입니다.

마치 스위스 아미 나이프처럼 다양한 도구가 준비되어 있어, 텍스트를 원하는 대로 조작할 수 있게 해줍니다.

개요

간단히 말해서, 문자열 메서드는 텍스트를 검색, 변환, 분리, 결합하는 다양한 기능을 제공합니다. 실무에서 여러분이 사용자 입력을 정제하거나, 로그 파일을 파싱하거나, API 응답을 처리하거나, 문서를 분석할 때 문자열 메서드가 필요합니다.

예를 들어, 사용자가 입력한 공백을 제거하거나, 모든 이메일 주소를 찾거나, CSV 데이터를 파싱할 때 매우 유용합니다. 기존에는 복잡한 반복문과 조건문으로 텍스트를 처리했다면, 이제는 간단한 메서드 호출로 같은 작업을 할 수 있습니다.

문자열 메서드의 핵심 특징은 첫째, 원본을 변경하지 않고 새로운 문자열을 반환하며, 둘째, 메서드 체이닝이 가능하고, 셋째, 대부분의 일반적인 텍스트 작업에 대한 내장 메서드가 있다는 점입니다. 이러한 특징들 덕분에 텍스트 처리가 간결하고 안전하며 효율적입니다.

코드 예제

# 다양한 문자열 메서드 활용
email = "  User@Example.COM  "

# 공백 제거 및 소문자 변환
clean_email = email.strip().lower()
print(f"정제된 이메일: {clean_email}")

# 문자열 분리
username, domain = clean_email.split("@")
print(f"사용자: {username}, 도메인: {domain}")

# 문자열 검색 및 치환
text = "Python is great. Python is easy."
new_text = text.replace("Python", "프로그래밍")
print(new_text)

# 문자열 포맷팅
name = "철수"
age = 25
message = f"{name}님은 {age}세입니다."
print(message)

# 문자열 결합
words = ["Hello", "World", "Python"]
sentence = " ".join(words)
print(sentence)

설명

이것이 하는 일: 사용자 입력 문자열을 정제하고, 분리하고, 검색하고, 변환하는 다양한 텍스트 처리 작업을 수행합니다. 첫 번째로, email.strip()은 문자열 앞뒤의 공백을 제거합니다.

사용자가 실수로 입력한 공백 때문에 발생하는 버그를 방지할 수 있습니다. .lower()는 모든 문자를 소문자로 변환하며, 메서드 체이닝으로 strip().lower() 같이 연속해서 호출할 수 있습니다.

이는 원본 email을 변경하지 않고 새로운 문자열을 반환합니다. 그 다음으로, split("@")는 문자열을 @를 기준으로 나누어 리스트로 반환합니다.

"user@example.com".split("@")["user", "example.com"]을 반환하며, 이를 username, domain = ... 구문으로 두 변수에 각각 할당할 수 있습니다. 이는 CSV 파싱이나 로그 분석에서 매우 유용합니다.

세 번째로, replace("Python", "프로그래밍")은 문자열에서 "Python"을 모두 찾아 "프로그래밍"으로 바꿉니다. 모든 출현을 바꾸며, 특정 개수만 바꾸려면 replace("Python", "프로그래밍", 1) 같이 세 번째 인자로 횟수를 지정할 수 있습니다.

네 번째로, f-string은 문자열 앞에 f를 붙이고 중괄호 안에 변수나 표현식을 넣는 방식입니다. f"{name}님은 {age}세입니다."는 변수의 값을 자동으로 문자열에 삽입하며, {age + 1} 같은 표현식도 가능합니다.

Python 3.6 이상에서 사용 가능하며 가장 권장되는 방식입니다. 마지막으로, " ".join(words)는 리스트의 모든 문자열을 공백으로 연결합니다.

join 앞의 문자열(" ")이 구분자가 되며, ", ".join(words)처럼 다른 구분자도 사용할 수 있습니다. 이는 split()의 반대 작업입니다.

여러분이 이 코드를 사용하면 텍스트 데이터를 자유자재로 다룰 수 있습니다. 사용자 입력 검증, 데이터 정제, 보고서 생성, 웹 스크래핑 등 실무의 대부분의 텍스트 작업을 간단한 메서드로 해결할 수 있으며, 코드도 훨씬 읽기 쉬워집니다.

실전 팁

💡 문자열이 특정 패턴으로 시작하거나 끝나는지 확인할 때는 startswith(), endswith()를 사용하세요. 예: email.endswith(".com")

💡 문자열에 특정 문자만 있는지 확인하려면 isdigit(), isalpha(), isalnum() 같은 메서드를 사용하세요. 입력 검증에 유용합니다.

💡 복잡한 패턴 매칭은 정규표현식을 사용하세요. import re로 re 모듈을 가져와 re.search(), re.findall() 등을 활용합니다.

💡 큰 텍스트를 반복적으로 결합할 때는 += 대신 리스트에 모아서 "".join()을 사용하세요. 성능이 훨씬 좋습니다.

💡 문자열의 특정 위치의 문자에 접근하려면 인덱싱과 슬라이싱을 사용하세요. 예: email[0]은 첫 문자, email[1:5]는 2번째부터 5번째 문자까지입니다.


8. 예외 처리 - 에러를 우아하게 다루기

시작하며

여러분이 사용자에게 나이를 입력받는데, 사용자가 숫자 대신 "스물다섯"이라고 입력했다고 상상해보세요. 프로그램이 갑자기 중단되고 에러 메시지가 터진다면 사용자는 당황할 것입니다.

이런 문제는 실무에서 항상 발생합니다. 파일이 없거나, 네트워크가 끊기거나, 사용자가 잘못된 입력을 하는 등 예상하지 못한 상황은 언제든지 일어납니다.

이런 에러를 처리하지 않으면 프로그램이 죽어버립니다. 바로 이럴 때 필요한 것이 예외 처리입니다.

마치 안전망처럼 에러가 발생해도 프로그램이 중단되지 않고 우아하게 대처할 수 있게 해줍니다.

개요

간단히 말해서, 예외 처리는 에러가 발생했을 때 프로그램이 중단되지 않고 대안적인 동작을 수행하게 만드는 메커니즘입니다. 실무에서 여러분이 파일을 읽거나, API를 호출하거나, 데이터베이스에 접근하거나, 사용자 입력을 처리할 때 예외 처리가 필요합니다.

예를 들어, 파일이 없을 때 새로 만들거나, 네트워크 에러가 발생하면 재시도하거나, 잘못된 입력에 친절한 메시지를 보여줄 때 매우 유용합니다. 기존에는 에러가 나면 프로그램이 죽었다면, 이제는 에러를 감지하고 적절하게 처리할 수 있습니다.

예외 처리의 핵심 특징은 첫째, try 블록에서 에러가 날 수 있는 코드를 실행하고, 둘째, except 블록에서 특정 에러를 잡아 처리하며, 셋째, finally 블록에서 에러 여부와 관계없이 정리 작업을 수행한다는 점입니다. 이러한 특징들 덕분에 안정적이고 사용자 친화적인 프로그램을 만들 수 있습니다.

코드 예제

# 사용자 입력을 안전하게 처리
def get_user_age():
    try:
        age_input = input("나이를 입력하세요: ")
        age = int(age_input)  # 에러가 날 수 있는 부분

        if age < 0 or age > 150:
            raise ValueError("나이는 0~150 사이여야 합니다.")

        return age

    except ValueError as e:
        print(f"입력 오류: {e}")
        return None

    except Exception as e:
        print(f"예상치 못한 오류: {e}")
        return None

    finally:
        print("입력 처리 완료")

# 함수 사용
user_age = get_user_age()
if user_age:
    print(f"입력된 나이: {user_age}세")

설명

이것이 하는 일: 사용자 입력을 받아 정수로 변환하고, 발생할 수 있는 다양한 에러를 감지하여 적절히 처리합니다. 첫 번째로, try: 블록 안에는 에러가 발생할 수 있는 코드를 넣습니다.

int(age_input)은 문자열을 정수로 변환하는데, 사용자가 "abc" 같은 숫자가 아닌 값을 입력하면 ValueError가 발생합니다. try 블록은 "이 코드를 실행해보되, 에러가 나면 except로 가라"는 의미입니다.

그 다음으로, raise ValueError(...)는 의도적으로 예외를 발생시키는 것입니다. 나이가 유효 범위를 벗어나면 직접 에러를 발생시켜 except 블록에서 처리하게 합니다.

이는 비즈니스 로직을 검증하고 일관되게 에러를 다루는 방법입니다. 세 번째로, except ValueError as e: 블록은 ValueError 타입의 예외만 잡습니다.

as e는 예외 객체를 e 변수에 할당하여 에러 메시지를 출력할 수 있게 합니다. 여러 개의 except 블록을 두어 각각의 에러 타입에 맞게 대응할 수 있으며, 위에서 아래로 순서대로 검사됩니다.

네 번째로, except Exception as e: 블록은 모든 예외를 잡는 포괄적인 핸들러입니다. 특정 에러로 잡히지 않은 모든 에러가 여기로 옵니다.

항상 구체적인 예외를 먼저 처리하고, 마지막에 일반 예외를 처리해야 합니다. 마지막으로, finally: 블록은 에러 발생 여부와 관계없이 항상 실행됩니다.

파일을 닫거나, 데이터베이스 연결을 종료하거나, 로그를 남기는 등의 정리 작업에 사용됩니다. return이 있어도 finally는 반드시 실행됩니다.

여러분이 이 코드를 사용하면 예상치 못한 상황에서도 프로그램이 안정적으로 동작합니다. 사용자에게 친절한 에러 메시지를 보여주고, 시스템 자원을 안전하게 정리하며, 프로덕션 환경에서 서비스가 중단되는 것을 방지할 수 있습니다.

실전 팁

💡 구체적인 예외를 먼저 잡고, 일반적인 예외는 나중에 잡으세요. except Exception:을 맨 위에 두면 모든 에러를 잡아버려 디버깅이 어려워집니다.

💡 빈 except 블록(except:)은 사용하지 마세요. 최소한 except Exception as e:로 어떤 에러인지 로그를 남기세요.

💡 파일 작업은 with 문을 사용하세요. with open("file.txt") as f:는 자동으로 파일을 닫아주므로 finally가 필요 없습니다.

💡 예외를 무시하지 마세요. 적어도 로깅은 해야 나중에 문제를 추적할 수 있습니다. import logging으로 로깅 모듈을 사용하세요.

💡 사용자 정의 예외를 만들 수 있습니다. class InvalidAgeError(Exception): pass 같이 Exception을 상속받아 도메인 특화 예외를 만들면 코드가 더 명확해집니다.


#Python#변수#데이터타입#리스트#딕셔너리#Data Science