본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.
본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.
이미지 로딩 중...
AI Generated
2025. 12. 15. · 11 Views
파이썬 기초 복습 완벽 가이드
파이썬의 핵심 개념을 처음부터 다시 정리하는 입문서입니다. 변수부터 함수까지, 실무에서 가장 많이 사용하는 기초 문법을 쉬운 예제와 함께 배웁니다. 초급 개발자가 반드시 알아야 할 파이썬 필수 개념을 담았습니다.
목차
1. 변수와 데이터 타입
어느 날 김개발 씨가 처음으로 파이썬 프로젝트를 맡게 되었습니다. 설레는 마음으로 코드를 작성하기 시작했지만, 변수에 값을 저장하다가 문득 궁금해졌습니다.
"이 변수의 타입은 뭐지?"
변수는 데이터를 담는 그릇입니다. 파이썬에서는 변수에 값을 할당할 때 자동으로 타입이 결정됩니다.
정수, 실수, 문자열, 불린 등 다양한 데이터 타입이 있으며, 각각의 특성을 이해하면 더 정확한 코드를 작성할 수 있습니다.
다음 코드를 살펴봅시다.
# 정수형 변수
age = 25
print(type(age)) # <class 'int'>
# 실수형 변수
height = 175.5
print(type(height)) # <class 'float'>
# 문자열 변수
name = "김개발"
print(type(name)) # <class 'str'>
# 불린 변수
is_developer = True
print(type(is_developer)) # <class 'bool'>
김개발 씨는 입사 1개월 차 주니어 개발자입니다. 오늘도 열심히 파이썬 코드를 작성하던 중, 변수에 값을 저장했는데 예상과 다른 결과가 나왔습니다.
분명히 맞게 작성한 것 같은데 왜 원하는 대로 동작하지 않는 걸까요? 선배 개발자 박시니어 씨가 다가와 코드를 살펴봅니다.
"아, 여기가 문제네요. 데이터 타입을 제대로 이해하지 못해서 생긴 실수예요." 그렇다면 변수와 데이터 타입이란 정확히 무엇일까요?
쉽게 비유하자면, 변수는 마치 택배 상자와 같습니다. 상자에 물건을 담듯이 변수에는 데이터를 담습니다.
그리고 상자에 담긴 물건의 종류가 다르듯이, 변수에 담기는 데이터의 종류도 다릅니다. 이 데이터의 종류를 데이터 타입이라고 부릅니다.
변수와 데이터 타입을 제대로 구분하지 못하면 어떤 일이 벌어질까요? 예를 들어, 숫자처럼 보이는 "123"이라는 문자열과 진짜 숫자 123은 완전히 다릅니다.
문자열 "123"에 1을 더하려고 하면 에러가 발생합니다. 또한 계산 결과가 예상과 달라질 수 있습니다.
프로젝트가 커질수록 이런 타입 혼동은 찾기 어려운 버그가 됩니다. 바로 이런 문제를 방지하기 위해 데이터 타입을 정확히 이해해야 합니다.
파이썬에는 크게 네 가지 기본 타입이 있습니다. 첫 번째는 **정수형(int)**으로 소수점이 없는 숫자입니다.
두 번째는 **실수형(float)**으로 소수점이 있는 숫자입니다. 세 번째는 **문자열(str)**로 따옴표로 감싼 텍스트입니다.
네 번째는 **불린(bool)**으로 참(True) 또는 거짓(False)을 나타냅니다. 위의 코드를 한 줄씩 살펴보겠습니다.
먼저 age 변수에 25를 할당하면 자동으로 정수형이 됩니다. type() 함수로 확인하면 int 클래스라고 출력됩니다.
다음으로 height 변수에 175.5를 할당하면 실수형이 됩니다. 소수점이 있으면 자동으로 float 타입이 됩니다.
name 변수에는 따옴표로 감싼 텍스트를 넣어서 문자열이 되었고, is_developer에는 True를 넣어서 불린 타입이 되었습니다. 실제 현업에서는 어떻게 활용할까요?
예를 들어 쇼핑몰 서비스를 개발한다고 가정해봅시다. 상품 가격은 정수나 실수로, 상품명은 문자열로, 재고 여부는 불린으로 저장합니다.
올바른 타입을 사용하면 계산도 정확하고 데이터베이스 설계도 깔끔해집니다. 많은 기업에서 코드 리뷰 시 타입 사용을 중요하게 체크합니다.
하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수 중 하나는 숫자처럼 보이는 문자열을 그냥 계산에 사용하는 것입니다.
"100" + "200"은 "100200"이라는 문자열이 되어버립니다. 따라서 int()나 float() 함수로 타입을 명시적으로 변환해야 합니다.
다시 김개발 씨의 이야기로 돌아가 봅시다. 박시니어 씨의 설명을 들은 김개발 씨는 고개를 끄덕였습니다.
"아, 그래서 그랬군요! 타입을 확인하고 필요하면 변환해야 하는군요." 데이터 타입을 제대로 이해하면 더 정확하고 예측 가능한 코드를 작성할 수 있습니다.
여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.
실전 팁
💡 - type() 함수로 변수의 타입을 언제든지 확인할 수 있습니다
- int(), float(), str() 함수로 타입을 명시적으로 변환하세요
- 계산이 필요한 데이터는 숫자 타입으로 저장하는 것이 좋습니다
2. 리스트와 튜플 다루기
김개발 씨가 여러 개의 상품 데이터를 처리해야 하는 기능을 맡았습니다. 변수 하나에 값 하나만 담는 방법으로는 도저히 해결할 수 없었습니다.
"여러 개의 데이터를 한 번에 관리할 방법은 없을까요?"
리스트는 여러 개의 데이터를 순서대로 담는 자료구조입니다. 대괄호로 생성하며 언제든지 값을 추가하거나 수정할 수 있습니다.
튜플은 리스트와 비슷하지만 한 번 생성하면 수정할 수 없다는 차이가 있습니다. 각각의 특성을 이해하고 상황에 맞게 사용하면 효율적인 코드를 작성할 수 있습니다.
다음 코드를 살펴봅시다.
# 리스트 생성 및 조작
fruits = ["사과", "바나나", "딸기"]
print(fruits[0]) # 사과 (인덱스로 접근)
fruits.append("오렌지") # 리스트에 추가
print(fruits) # ['사과', '바나나', '딸기', '오렌지']
fruits[1] = "포도" # 값 수정 가능
print(fruits) # ['사과', '포도', '딸기', '오렌지']
# 튜플은 수정 불가능
coordinates = (37.5665, 126.9780)
# coordinates[0] = 40.0 # 에러 발생!
김개발 씨는 이번 주에 상품 목록 관리 기능을 개발하라는 과제를 받았습니다. 상품이 10개, 100개씩 늘어나는데 변수를 하나씩 만들 수는 없는 노릇입니다.
막막해진 김개발 씨는 다시 박시니어 씨를 찾아갔습니다. 박시니어 씨가 웃으면서 말합니다.
"그럴 때 쓰라고 리스트가 있는 거예요." 그렇다면 리스트란 정확히 무엇일까요? 쉽게 비유하자면, 리스트는 마치 기차의 객실과 같습니다.
한 칸 한 칸에 승객(데이터)이 앉아 있고, 객실 번호(인덱스)로 각 승객을 찾을 수 있습니다. 원하면 중간에 객실을 추가하거나 승객을 바꿀 수도 있습니다.
이처럼 리스트도 여러 데이터를 순서대로 담고 자유롭게 변경할 수 있는 자료구조입니다. 리스트가 없던 시절에는 어땠을까요?
개발자들은 비슷한 데이터를 관리하기 위해 변수를 여러 개 선언해야 했습니다. fruit1, fruit2, fruit3처럼 말이죠.
코드가 길어지고, 데이터가 몇 개인지 추적하기도 어려웠습니다. 더 큰 문제는 데이터 개수가 동적으로 변할 때였습니다.
미리 변수를 몇 개나 만들어야 할지 알 수 없었으니까요. 바로 이런 문제를 해결하기 위해 리스트가 등장했습니다.
리스트를 사용하면 하나의 변수로 여러 데이터를 관리할 수 있습니다. 또한 append() 메서드로 데이터를 추가하거나, 인덱스로 특정 위치의 값을 수정할 수 있습니다.
무엇보다 반복문과 함께 사용하면 모든 데이터를 편리하게 처리할 수 있다는 큰 이점이 있습니다. 위의 코드를 한 줄씩 살펴보겠습니다.
먼저 대괄호로 리스트를 생성하고 세 개의 과일 이름을 담았습니다. 인덱스는 0부터 시작하므로 fruits[0]은 "사과"입니다.
이 부분이 핵심입니다. 다음으로 append() 메서드로 "오렌지"를 추가했습니다.
리스트 끝에 새로운 요소가 추가됩니다. 그리고 fruits[1]에 "포도"를 할당해서 기존 값을 수정했습니다.
그런데 튜플은 리스트와 무엇이 다를까요? 튜플은 소괄호로 생성하며, 한 번 만들어지면 수정할 수 없습니다.
위도와 경도처럼 변경되면 안 되는 데이터를 저장할 때 유용합니다. 실수로 값을 바꾸려고 하면 에러가 발생해서 데이터 안전성을 보장합니다.
실제 현업에서는 어떻게 활용할까요? 예를 들어 쇼핑몰에서 장바구니를 구현한다고 가정해봅시다.
사용자가 선택한 상품들을 리스트에 저장하고, 추가/삭제 기능을 제공합니다. 반면 상품의 고유 ID나 생성 시각처럼 변경되면 안 되는 정보는 튜플에 저장합니다.
많은 기업에서 이런 패턴을 적극적으로 사용하고 있습니다. 하지만 주의할 점도 있습니다.
초보 개발자들이 흔히 하는 실수 중 하나는 인덱스 범위를 벗어나는 접근입니다. 요소가 3개인 리스트에서 fruits[5]에 접근하면 에러가 발생합니다.
따라서 len() 함수로 길이를 확인하거나, 안전하게 반복문을 사용해야 합니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.
박시니어 씨의 설명을 들은 김개발 씨는 눈이 반짝였습니다. "리스트를 쓰면 이렇게 편하게 관리할 수 있군요!" 리스트와 튜플을 제대로 이해하면 여러 데이터를 효율적으로 관리하는 코드를 작성할 수 있습니다.
여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.
실전 팁
💡 - 인덱스는 항상 0부터 시작한다는 점을 기억하세요
- 수정이 필요하면 리스트, 수정이 불필요하면 튜플을 사용하세요
- len() 함수로 리스트의 길이를 확인할 수 있습니다
3. 딕셔너리 활용법
김개발 씨가 사용자 정보를 관리하는 기능을 개발하게 되었습니다. 이름, 나이, 이메일 등 여러 속성을 저장해야 하는데, 리스트로는 어떤 값이 무엇을 의미하는지 알기 어려웠습니다.
"데이터에 이름표를 붙일 수는 없을까요?"
딕셔너리는 키와 값의 쌍으로 데이터를 저장하는 자료구조입니다. 중괄호로 생성하며, 키를 통해 값에 빠르게 접근할 수 있습니다.
순서가 아닌 의미로 데이터를 관리할 때 매우 유용하며, JSON 형태의 데이터를 다룰 때도 자주 사용됩니다.
다음 코드를 살펴봅시다.
# 딕셔너리 생성
user = {
"name": "김개발",
"age": 25,
"email": "kim@example.com"
}
# 키로 값 접근
print(user["name"]) # 김개발
# 새로운 키-값 추가
user["job"] = "개발자"
# 키가 있는지 확인
if "email" in user:
print("이메일:", user["email"])
김개발 씨는 이번에 회원 관리 시스템을 만들게 되었습니다. 한 사용자의 정보를 리스트에 담아봤지만, user_data[0]이 이름인지 나이인지 매번 헷갈렸습니다.
코드를 읽는 사람도 인덱스만 보고는 무슨 데이터인지 알 수 없었습니다. 선배 개발자 박시니어 씨가 지나가다가 말합니다.
"데이터에 의미를 붙이고 싶으면 딕셔너리를 쓰세요." 그렇다면 딕셔너리란 정확히 무엇일까요? 쉽게 비유하자면, 딕셔너리는 마치 실제 사전과 같습니다.
단어(키)를 찾으면 그 뜻(값)을 알 수 있습니다. 단어 순서는 중요하지 않고, 원하는 단어만 빠르게 찾을 수 있습니다.
이처럼 딕셔너리도 키를 통해 값에 바로 접근하는 구조입니다. 딕셔너리가 없던 시절에는 어땠을까요?
개발자들은 여러 리스트를 만들어서 관리했습니다. names 리스트, ages 리스트, emails 리스트처럼 말이죠.
같은 사용자의 정보가 여러 리스트에 흩어져 있어서 관리가 복잡했습니다. 더 큰 문제는 인덱스를 맞춰야 한다는 점이었습니다.
한 리스트에 요소를 추가하면 다른 리스트도 같은 위치에 추가해야 했으니까요. 바로 이런 문제를 해결하기 위해 딕셔너리가 등장했습니다.
딕셔너리를 사용하면 관련된 데이터를 하나의 객체로 묶을 수 있습니다. 또한 키 이름만 보고도 어떤 데이터인지 직관적으로 알 수 있습니다.
무엇보다 특정 값을 찾을 때 인덱스가 아닌 의미 있는 키로 접근할 수 있다는 큰 이점이 있습니다. 위의 코드를 한 줄씩 살펴보겠습니다.
먼저 중괄호로 딕셔너리를 생성하고, 세 개의 키-값 쌍을 정의했습니다. "name"이라는 키에 "김개발"이라는 값을 연결했습니다.
이 부분이 핵심입니다. 다음으로 대괄호 안에 키를 넣어서 값을 조회했습니다.
user["job"] = "개발자"로 새로운 키-값 쌍을 추가할 수도 있습니다. in 연산자로 특정 키가 존재하는지 확인한 후 안전하게 접근할 수 있습니다.
실제 현업에서는 어떻게 활용할까요? 예를 들어 API를 통해 JSON 데이터를 주고받는 상황을 가정해봅시다.
JSON은 딕셔너리와 거의 같은 구조입니다. 서버에서 받은 사용자 정보를 딕셔너리로 파싱하고, 필요한 값을 키로 추출해서 화면에 표시합니다.
거의 모든 웹 서비스에서 이런 패턴을 사용하고 있습니다. 딕셔너리에는 유용한 메서드가 많이 있습니다.
keys() 메서드는 모든 키를 가져오고, values()는 모든 값을 가져옵니다. items()는 키-값 쌍을 튜플로 가져옵니다.
get() 메서드는 키가 없을 때 에러 대신 기본값을 반환해서 안전하게 값을 조회할 수 있습니다. 하지만 주의할 점도 있습니다.
초보 개발자들이 흔히 하는 실수 중 하나는 존재하지 않는 키에 접근하는 것입니다. user["phone"]처럼 없는 키를 조회하면 KeyError가 발생합니다.
따라서 in 연산자로 먼저 확인하거나, get() 메서드를 사용해야 합니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.
박시니어 씨의 설명을 들은 김개발 씨는 감탄했습니다. "이제 코드가 훨씬 읽기 쉬워졌어요!" 딕셔너리를 제대로 이해하면 더 직관적이고 관리하기 쉬운 데이터 구조를 만들 수 있습니다.
여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.
실전 팁
💡 - 키가 있는지 확인하려면 in 연산자를 사용하세요
- get() 메서드를 사용하면 KeyError를 방지할 수 있습니다
- 딕셔너리는 순서를 보장하지 않으므로 순서가 중요하면 리스트를 사용하세요
4. for문과 while문
김개발 씨가 100개의 상품 데이터를 처리해야 하는 작업을 맡았습니다. 하나하나 코드를 작성하려니 끝이 보이지 않았습니다.
"같은 작업을 반복하는 더 좋은 방법은 없을까요?"
반복문은 같은 작업을 여러 번 수행할 때 사용하는 제어 구조입니다. for문은 정해진 횟수만큼 반복하거나 리스트의 요소를 순회할 때 유용하고, while문은 특정 조건이 만족될 때까지 반복할 때 사용합니다.
올바른 반복문을 선택하면 코드를 간결하고 효율적으로 작성할 수 있습니다.
다음 코드를 살펴봅시다.
# for문으로 리스트 순회
fruits = ["사과", "바나나", "딸기"]
for fruit in fruits:
print(f"{fruit}를 좋아합니다")
# range를 사용한 반복
for i in range(5):
print(f"{i}번째 반복")
# while문으로 조건 반복
count = 0
while count < 3:
print(f"카운트: {count}")
count += 1 # 무한 루프 방지를 위해 반드시 증가
김개발 씨는 오늘 상품 목록을 처리하는 배치 작업을 만들어야 합니다. 상품이 100개나 되는데, 하나씩 print() 함수를 100번 쓸 수는 없는 노릇입니다.
어떻게 해야 할지 막막해진 김개발 씨는 또다시 박시니어 씨를 찾아갔습니다. 박시니어 씨가 미소를 지으며 말합니다.
"반복 작업에는 반복문을 쓰는 거예요." 그렇다면 반복문이란 정확히 무엇일까요? 쉽게 비유하자면, 반복문은 마치 세탁기의 헹굼 과정과 같습니다.
헹굼은 3회, 5회처럼 정해진 횟수만큼 같은 동작을 반복합니다. 또는 물이 깨끗해질 때까지 계속 헹굽니다.
이처럼 반복문도 정해진 횟수나 조건에 따라 같은 코드를 여러 번 실행하는 구조입니다. 반복문이 없던 시절에는 어땠을까요?
개발자들은 같은 코드를 복사해서 붙여넣기를 수십 번 해야 했습니다. 코드가 엄청나게 길어지고, 나중에 수정할 때도 모든 곳을 찾아서 바꿔야 했습니다.
더 큰 문제는 반복 횟수를 미리 알 수 없을 때였습니다. 데이터가 몇 개인지 모르면 코드를 얼마나 작성해야 할지 알 수 없었으니까요.
바로 이런 문제를 해결하기 위해 반복문이 등장했습니다. for문을 사용하면 리스트의 모든 요소를 자동으로 순회할 수 있습니다.
또한 range() 함수와 함께 쓰면 정확히 원하는 횟수만큼 반복할 수 있습니다. while문은 조건이 참인 동안 계속 실행되므로 언제 끝날지 모르는 작업에 유용합니다.
위의 코드를 한 줄씩 살펴보겠습니다. 먼저 for문은 fruits 리스트의 요소를 하나씩 꺼내서 fruit 변수에 담습니다.
그리고 반복문 안의 코드를 실행합니다. 이 부분이 핵심입니다.
range(5)는 0부터 4까지 숫자를 생성해서 5번 반복합니다. while문은 count가 3보다 작은 동안 계속 실행되며, count를 증가시켜서 언젠가는 반복이 끝나도록 만들어야 합니다.
for문과 while문은 언제 구분해서 사용할까요? 리스트나 딕셔너리처럼 순회할 대상이 명확하면 for문을 사용합니다.
반면 사용자 입력을 받거나 특정 조건을 만족할 때까지 기다리는 경우에는 while문이 적합합니다. 예를 들어 로그인 시도를 3번까지 허용하는 로직은 while문으로 구현할 수 있습니다.
실제 현업에서는 어떻게 활용할까요? 예를 들어 쇼핑몰에서 전체 상품의 가격을 10% 할인하는 이벤트를 진행한다고 가정해봅시다.
for문으로 모든 상품을 순회하면서 가격을 수정합니다. 또는 재고가 0인 상품을 찾을 때까지 계속 검색하는 로직은 while문으로 구현할 수 있습니다.
거의 모든 서비스에서 반복문을 활용합니다. 반복문에는 유용한 키워드가 있습니다.
break는 반복문을 즉시 종료하고, continue는 현재 반복을 건너뛰고 다음 반복으로 넘어갑니다. 특정 조건에서 반복을 중단하거나 일부 요소를 건너뛸 때 매우 유용합니다.
하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수 중 하나는 무한 루프입니다.
while문에서 조건이 절대 거짓이 되지 않으면 프로그램이 멈추지 않습니다. 따라서 반드시 조건을 변경하는 코드를 넣어야 합니다.
또한 for문에서 리스트를 수정하면서 순회하면 예상치 못한 결과가 나올 수 있으니 주의해야 합니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.
박시니어 씨의 설명을 들은 김개발 씨는 감탄했습니다. "반복문으로 이렇게 간단하게 처리할 수 있군요!" 반복문을 제대로 이해하면 중복 코드를 제거하고 효율적으로 데이터를 처리할 수 있습니다.
여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.
실전 팁
💡 - 순회할 대상이 명확하면 for문, 조건이 중요하면 while문을 사용하세요
- 무한 루프를 방지하기 위해 while문에는 반드시 종료 조건을 만드세요
- break와 continue를 활용하면 반복문을 더 세밀하게 제어할 수 있습니다
5. 조건문 if-else
김개발 씨가 로그인 기능을 개발하던 중 문득 궁금해졌습니다. "비밀번호가 맞을 때와 틀릴 때 다른 동작을 하려면 어떻게 해야 하지?" 상황에 따라 다르게 동작하는 코드가 필요했습니다.
조건문은 특정 조건에 따라 다른 코드를 실행하는 제어 구조입니다. if문으로 조건을 검사하고, elif로 추가 조건을 검사하며, else로 모든 조건이 거짓일 때의 동작을 정의합니다.
조건문을 올바르게 사용하면 프로그램이 상황에 맞게 지능적으로 동작할 수 있습니다.
다음 코드를 살펴봅시다.
# 기본 if-else 구조
age = 20
if age >= 19:
print("성인입니다")
else:
print("미성년자입니다")
# elif를 사용한 다중 조건
score = 85
if score >= 90:
grade = "A"
elif score >= 80:
grade = "B"
elif score >= 70:
grade = "C"
else:
grade = "F"
print(f"학점: {grade}")
김개발 씨는 이번에 회원 등급 시스템을 개발하게 되었습니다. 구매 금액에 따라 일반, 실버, 골드 등급으로 나누어야 하는데, 모든 경우를 똑같이 처리할 수는 없었습니다.
상황에 따라 다르게 동작하는 코드가 필요했습니다. 선배 개발자 박시니어 씨가 지나가다가 말합니다.
"조건에 따라 분기하고 싶으면 if문을 쓰세요." 그렇다면 조건문이란 정확히 무엇일까요? 쉽게 비유하자면, 조건문은 마치 교차로의 신호등과 같습니다.
초록불이면 직진하고, 빨간불이면 멈춥니다. 신호의 상태에 따라 운전자의 행동이 달라집니다.
이처럼 조건문도 조건이 참인지 거짓인지에 따라 실행하는 코드를 선택하는 구조입니다. 조건문이 없던 시절에는 어땠을까요?
개발자들은 모든 경우를 따로따로 처리해야 했습니다. 코드가 복잡해지고, 새로운 조건이 추가될 때마다 전체 구조를 다시 짜야 했습니다.
더 큰 문제는 예외 상황을 처리하기 어렵다는 점이었습니다. 사용자가 예상치 못한 값을 입력하면 프로그램이 오작동했으니까요.
바로 이런 문제를 해결하기 위해 조건문이 등장했습니다. if문을 사용하면 조건이 참일 때만 특정 코드를 실행할 수 있습니다.
elif는 첫 번째 조건이 거짓일 때 다음 조건을 검사합니다. else는 모든 조건이 거짓일 때 실행되는 기본 동작을 정의합니다.
이렇게 여러 조건을 체계적으로 검사할 수 있습니다. 위의 코드를 한 줄씩 살펴보겠습니다.
먼저 age가 19 이상인지 검사합니다. 조건이 참이면 "성인입니다"를 출력하고, 거짓이면 else 블록의 코드를 실행합니다.
이 부분이 핵심입니다. 두 번째 예제에서는 점수에 따라 학점을 매기는데, 위에서부터 순서대로 조건을 검사합니다.
90점 이상이면 A, 80점 이상이면 B처럼 말이죠. 어느 조건에도 맞지 않으면 F를 부여합니다.
조건문에서는 비교 연산자와 논리 연산자를 자주 사용합니다. 비교 연산자에는 ==, !=, >, <, >=, <= 등이 있습니다.
논리 연산자 and는 모든 조건이 참일 때, or는 하나라도 참일 때, not은 조건을 반대로 만듭니다. 이들을 조합하면 복잡한 조건도 표현할 수 있습니다.
실제 현업에서는 어떻게 활용할까요? 예를 들어 쇼핑몰에서 쿠폰 적용 로직을 만든다고 가정해봅시다.
구매 금액이 5만 원 이상이고 신규 회원이면 20% 할인, 일반 회원이면 10% 할인처럼 복잡한 조건을 처리합니다. 로그인 검증, 권한 체크, 입력 유효성 검사 등 거의 모든 기능에 조건문이 사용됩니다.
조건문을 작성할 때는 순서가 중요합니다. elif는 위에서부터 순서대로 검사하므로, 더 구체적인 조건을 먼저 배치해야 합니다.
예를 들어 점수가 100점인 경우를 특별히 처리하려면 가장 위에 if score == 100을 배치해야 합니다. 하지만 주의할 점도 있습니다.
초보 개발자들이 흔히 하는 실수 중 하나는 조건 순서를 잘못 배치하는 것입니다. if score >= 70을 먼저 쓰면 80점이나 90점도 C 학점이 되어버립니다.
따라서 높은 점수부터 검사하도록 순서를 조정해야 합니다. 또한 등호(=)와 동등 연산자(==)를 혼동하지 않도록 주의해야 합니다.
다시 김개발 씨의 이야기로 돌아가 봅시다. 박시니어 씨의 설명을 들은 김개발 씨는 고개를 끄덕였습니다.
"조건문으로 상황에 맞는 처리를 할 수 있군요!" 조건문을 제대로 이해하면 프로그램이 상황에 따라 지능적으로 동작하도록 만들 수 있습니다. 여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.
실전 팁
💡 - elif는 위에서부터 순서대로 검사하므로 조건 순서에 주의하세요
- and, or, not 연산자를 활용하면 복잡한 조건을 표현할 수 있습니다
- 등호(=)는 할당, 동등 연산자(==)는 비교입니다
6. 함수 정의와 호출
김개발 씨가 같은 계산 로직을 여러 곳에서 사용하게 되었습니다. 똑같은 코드를 복사해서 붙여넣다 보니 수정할 때마다 모든 곳을 찾아다녀야 했습니다.
"이 코드를 한 번만 작성하고 재사용할 수는 없을까요?"
함수는 특정 작업을 수행하는 코드를 묶어서 이름을 붙인 것입니다. def 키워드로 함수를 정의하고, 함수 이름으로 호출할 수 있습니다.
매개변수를 받아서 처리하고 return으로 결과를 반환합니다. 함수를 잘 활용하면 코드 재사용성이 높아지고 유지보수가 쉬워집니다.
다음 코드를 살펴봅시다.
# 함수 정의
def greet(name):
"""사용자에게 인사하는 함수"""
message = f"안녕하세요, {name}님!"
return message
# 함수 호출
result = greet("김개발")
print(result) # 안녕하세요, 김개발님!
# 기본값을 가진 매개변수
def calculate_price(price, discount=0.1):
"""할인된 가격을 계산하는 함수"""
return price * (1 - discount)
print(calculate_price(10000)) # 9000.0
print(calculate_price(10000, 0.2)) # 8000.0
김개발 씨는 이번 주에 가격 계산 로직을 여러 페이지에 구현해야 했습니다. 똑같은 할인 계산 코드를 10번이나 복사해서 붙여넣었더니, 나중에 계산 방식이 바뀌어서 10곳을 모두 수정해야 했습니다.
너무 비효율적이었습니다. 선배 개발자 박시니어 씨가 코드 리뷰를 하다가 말합니다.
"같은 코드를 반복하지 말고 함수로 만드세요." 그렇다면 함수란 정확히 무엇일까요? 쉽게 비유하자면, 함수는 마치 자판기와 같습니다.
돈을 넣으면(입력) 내부에서 음료를 선택하고 포장하는 과정을 거쳐(처리) 음료가 나옵니다(출력). 자판기의 내부 구조를 몰라도 사용할 수 있듯이, 함수도 내부 동작을 몰라도 호출만 하면 결과를 얻을 수 있습니다.
함수가 없던 시절에는 어땠을까요? 개발자들은 같은 로직을 필요할 때마다 새로 작성해야 했습니다.
코드가 중복되어 길어지고, 버그가 생기면 모든 곳을 찾아서 수정해야 했습니다. 더 큰 문제는 협업할 때였습니다.
다른 사람이 작성한 로직을 재사용하려면 코드를 통째로 복사해야 했으니까요. 바로 이런 문제를 해결하기 위해 함수가 등장했습니다.
함수를 사용하면 한 번 작성한 코드를 여러 곳에서 재사용할 수 있습니다. 또한 함수 이름으로 무슨 일을 하는지 명확하게 표현할 수 있습니다.
무엇보다 수정이 필요할 때 함수 하나만 고치면 모든 호출 부분에 자동으로 반영된다는 큰 이점이 있습니다. 위의 코드를 한 줄씩 살펴보겠습니다.
먼저 def 키워드로 함수를 정의하고 greet라는 이름을 붙였습니다. 괄호 안의 name은 매개변수로, 함수가 받을 입력값입니다.
이 부분이 핵심입니다. 함수 내부에서 인사 메시지를 만들고 return으로 결과를 반환합니다.
greet("김개발")처럼 함수 이름과 괄호로 호출하면 코드가 실행되고 결과가 반환됩니다. 두 번째 예제에서는 기본값을 가진 매개변수를 사용합니다.
discount=0.1처럼 기본값을 설정하면, 호출할 때 인자를 생략해도 기본값이 사용됩니다. calculate_price(10000)은 할인율을 주지 않아서 0.1이 적용되고, calculate_price(10000, 0.2)는 명시적으로 0.2를 전달합니다.
실제 현업에서는 어떻게 활용할까요? 예를 들어 쇼핑몰에서 배송비를 계산하는 로직을 함수로 만든다고 가정해봅시다.
calculate_shipping(weight, distance)처럼 무게와 거리를 받아서 배송비를 계산합니다. 장바구니, 주문 확인, 관리자 페이지 등 여러 곳에서 이 함수를 호출해서 일관된 계산 결과를 얻을 수 있습니다.
함수에는 중요한 개념들이 있습니다. **매개변수(parameter)**는 함수 정의에서 받을 값의 이름이고, **인자(argument)**는 실제로 전달하는 값입니다.
**반환값(return value)**은 함수가 처리한 결과입니다. return이 없으면 None이 반환됩니다.
이 개념들을 정확히 이해하면 함수를 더 효과적으로 사용할 수 있습니다. 하지만 주의할 점도 있습니다.
초보 개발자들이 흔히 하는 실수 중 하나는 함수가 너무 많은 일을 하도록 만드는 것입니다. 하나의 함수는 하나의 명확한 역할만 해야 합니다.
또한 return을 잊어버리면 함수가 None을 반환해서 예상치 못한 결과가 나올 수 있습니다. 함수 이름도 동사로 시작해서 무슨 일을 하는지 명확하게 표현해야 합니다.
다시 김개발 씨의 이야기로 돌아가 봅시다. 박시니어 씨의 설명을 들은 김개발 씨는 눈이 반짝였습니다.
"함수로 만들면 코드가 훨씬 깔끔해지고 관리하기 쉬워지네요!" 함수를 제대로 이해하면 재사용 가능하고 유지보수하기 쉬운 코드를 작성할 수 있습니다. 여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.
실전 팁
💡 - 함수는 하나의 명확한 역할만 수행하도록 작성하세요
- 함수 이름은 동사로 시작해서 무슨 일을 하는지 명확히 표현하세요
- 기본값을 활용하면 함수 호출이 더 유연해집니다
7. 리스트 컴프리헨션
김개발 씨가 리스트의 모든 요소를 제곱한 새 리스트를 만들어야 했습니다. for문으로 작성하니 코드가 길고 복잡해 보였습니다.
"더 간결하게 작성할 방법은 없을까요?"
리스트 컴프리헨션은 기존 리스트를 기반으로 새로운 리스트를 간결하게 생성하는 파이썬의 강력한 기능입니다. 한 줄로 반복문과 조건문을 표현할 수 있어서 코드가 짧아지고 가독성이 높아집니다.
데이터 변환이나 필터링 작업에 매우 유용합니다.
다음 코드를 살펴봅시다.
# 일반 for문 방식
numbers = [1, 2, 3, 4, 5]
squares = []
for num in numbers:
squares.append(num ** 2)
print(squares) # [1, 4, 9, 16, 25]
# 리스트 컴프리헨션 방식
numbers = [1, 2, 3, 4, 5]
squares = [num ** 2 for num in numbers]
print(squares) # [1, 4, 9, 16, 25]
# 조건을 포함한 리스트 컴프리헨션
even_squares = [num ** 2 for num in numbers if num % 2 == 0]
print(even_squares) # [4, 16]
김개발 씨는 이번에 데이터 전처리 작업을 맡게 되었습니다. 숫자 리스트를 변환하거나 필터링하는 코드를 작성하는데, for문으로 작성하니 코드가 여러 줄이 되어 복잡해 보였습니다.
더 간결하고 파이썬스러운 방법은 없을까요? 선배 개발자 박시니어 씨가 코드를 보고 말합니다.
"파이썬답게 작성하려면 리스트 컴프리헨션을 쓰세요." 그렇다면 리스트 컴프리헨션이란 정확히 무엇일까요? 쉽게 비유하자면, 리스트 컴프리헨션은 마치 공장의 자동화 라인과 같습니다.
원자재가 들어오면(기존 리스트) 한 번에 가공해서(변환) 완제품을 만듭니다(새 리스트). 여러 단계를 거치지 않고 한 번에 처리하므로 효율적입니다.
이처럼 리스트 컴프리헨션도 반복과 변환을 한 줄로 처리하는 강력한 문법입니다. 리스트 컴프리헨션이 없던 시절에는 어땠을까요?
개발자들은 빈 리스트를 만들고, for문으로 순회하며, append()로 요소를 추가하는 3단계를 거쳐야 했습니다. 코드가 길어지고, 임시 변수도 필요했습니다.
더 큰 문제는 코드를 읽을 때 전체 로직을 파악하기 어렵다는 점이었습니다. 반복문 안을 들여다봐야 무슨 일을 하는지 알 수 있었으니까요.
바로 이런 문제를 해결하기 위해 리스트 컴프리헨션이 등장했습니다. 리스트 컴프리헨션을 사용하면 한 줄로 리스트를 생성할 수 있습니다.
또한 코드의 의도가 명확하게 드러나서 가독성이 높아집니다. 무엇보다 파이썬의 내부 최적화 덕분에 일반 for문보다 빠르게 실행된다는 큰 이점이 있습니다.
위의 코드를 한 줄씩 살펴보겠습니다. 먼저 일반 for문 방식은 빈 리스트를 만들고, 반복문으로 각 요소를 제곱한 후 append()로 추가합니다.
반면 리스트 컴프리헨션은 대괄호 안에 [표현식 for 변수 in 리스트] 형태로 작성합니다. 이 부분이 핵심입니다.
num ** 2가 각 요소에 적용되고, 결과가 자동으로 새 리스트에 담깁니다. 조건을 추가할 수도 있습니다.
마지막 예제처럼 if 조건을 뒤에 붙이면 조건을 만족하는 요소만 처리됩니다. even_squares는 짝수만 제곱해서 담은 리스트입니다.
이렇게 필터링과 변환을 동시에 할 수 있습니다. 실제 현업에서는 어떻게 활용할까요?
예를 들어 쇼핑몰에서 전체 상품 리스트에서 재고가 있는 상품만 추출한다고 가정해봅시다. available_products = [p for p in products if p["stock"] > 0]처럼 간결하게 작성할 수 있습니다.
데이터 분석이나 API 응답 가공 작업에서도 리스트 컴프리헨션을 자주 사용합니다. 리스트 컴프리헨션은 다양한 형태로 활용할 수 있습니다.
중첩된 리스트를 평탄화하거나, 여러 리스트를 조합하거나, 딕셔너리 컴프리헨션으로 확장할 수도 있습니다. 하지만 너무 복잡하게 사용하면 오히려 가독성이 떨어지므로 적절한 수준에서 사용해야 합니다.
하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수 중 하나는 너무 복잡한 로직을 한 줄에 넣는 것입니다.
여러 조건이 중첩되거나 복잡한 계산이 필요하면 차라리 일반 for문을 사용하는 것이 좋습니다. 리스트 컴프리헨션은 간단한 변환과 필터링에 적합합니다.
또한 큰 데이터를 처리할 때는 메모리를 많이 사용할 수 있으니 제너레이터 표현식을 고려해야 합니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.
박시니어 씨의 설명을 들은 김개발 씨는 감탄했습니다. "한 줄로 이렇게 깔끔하게 작성할 수 있다니 놀랍네요!" 리스트 컴프리헨션을 제대로 이해하면 더 간결하고 파이썬스러운 코드를 작성할 수 있습니다.
여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.
실전 팁
💡 - 간단한 변환과 필터링에 리스트 컴프리헨션을 사용하세요
- 너무 복잡하면 일반 for문이 더 읽기 쉽습니다
- 딕셔너리 컴프리헨션, 집합 컴프리헨션도 같은 문법으로 사용할 수 있습니다
이상으로 학습을 마칩니다. 위 내용을 직접 코드로 작성해보면서 익혀보세요!
댓글 (0)
함께 보면 좋은 카드 뉴스
Helm 마이크로서비스 패키징 완벽 가이드
Kubernetes 환경에서 마이크로서비스를 효율적으로 패키징하고 배포하는 Helm의 핵심 기능을 실무 중심으로 학습합니다. Chart 생성부터 릴리스 관리까지 체계적으로 다룹니다.
보안 아키텍처 구성 완벽 가이드
프로젝트의 보안을 처음부터 설계하는 방법을 배웁니다. AWS 환경에서 VPC부터 WAF, 암호화, 접근 제어까지 실무에서 바로 적용할 수 있는 보안 아키텍처를 단계별로 구성해봅니다.
AWS Organizations 완벽 가이드
여러 AWS 계정을 체계적으로 관리하고 통합 결제와 보안 정책을 적용하는 방법을 실무 스토리로 쉽게 배워봅니다. 초보 개발자도 바로 이해할 수 있는 친절한 설명과 실전 예제를 제공합니다.
AWS KMS 암호화 완벽 가이드
AWS KMS(Key Management Service)를 활용한 클라우드 데이터 암호화 방법을 초급 개발자를 위해 쉽게 설명합니다. CMK 생성부터 S3, EBS 암호화, 봉투 암호화까지 실무에 필요한 모든 내용을 담았습니다.
AWS Secrets Manager 완벽 가이드
AWS에서 데이터베이스 비밀번호, API 키 등 민감한 정보를 안전하게 관리하는 Secrets Manager의 핵심 개념과 실무 활용법을 배워봅니다. 초급 개발자도 쉽게 따라할 수 있도록 실전 예제와 함께 설명합니다.