파이썬에서 데이터를 효율적으로 관리하고 처리하기 위해서는 리스트(List), 튜플(Tuple), **딕셔너리(Dictionary)**의 개념과 차이를 정확히 이해하는 것이 필수입니다. 각각의 자료구조는 용도와 특징이 다르므로, 상황에 맞게 적절히 선택하여 활용해야 합니다.
1. 리스트 (List): 유연하고 강력한 데이터 목록
기본 개념
- 정의: 여러 개의 데이터를 순서대로 저장하는 자료구조
- 기호: 대괄호 [ ] 사용
- 특징:
- 순서(인덱스)가 있음: 0번부터 시작하는 인덱스로 각 요소에 접근
- 수정, 추가, 삭제 가능: mutable(변경 가능) 자료형
- 중복 허용
- 다양한 데이터형 혼합 가능
리스트 생성과 특징
# 리스트는 대괄호[]로 생성한다
fruits = ['apple', 'banana', 'cherry']
# 파이썬의 리스트는 다른 프로그래밍 언어의 배열과 달리 다양한 데이터형을 섞을 수 있다
mixed_list = [1, 'hello', 3.14, True, [1, 2, 3]]
print(mixed_list) # [1, 'hello', 3.14, True, [1, 2, 3]]
리스트 접근과 조작
# 리스트는 음수값으로 접근할 수 있다
# 첨자는 맨 뒤에서부터 -1값으로 사용되는 것을 확인할 수 있다
fruits = ['apple', 'banana', 'cherry', 'date']
print(fruits[0]) # 'apple' (첫 번째)
print(fruits[-1]) # 'date' (마지막)
print(fruits[-2]) # 'cherry' (뒤에서 두 번째)
# 리스트에 접근할 때 콜론을 사용해 범위를 지정할 수 있다
# '리스트명[시작값:끝값+1]' 형식
print(fruits[1:3]) # ['banana', 'cherry']
print(fruits[:2]) # ['apple', 'banana'] (처음부터 1번까지)
print(fruits[2:]) # ['cherry', 'date'] (2번부터 끝까지)
# 리스트의 항목을 건너뛰며 추출할 수 있다 [::2] [::-2]
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print(numbers[::2]) # [0, 2, 4, 6, 8] (2칸씩 건너뛰기)
print(numbers[::-1]) # [9, 8, 7, 6, 5, 4, 3, 2, 1, 0] (역순)
print(numbers[::-2]) # [9, 7, 5, 3, 1] (역순으로 2칸씩)
# 값 수정
fruits[1] = 'orange'
print(fruits) # ['apple', 'orange', 'cherry', 'date']
# 값 추가
fruits.append('grape') # 끝에 추가
fruits.insert(1, 'kiwi') # 특정 위치에 추가
# 리스트의 항목을 삭제하려면 del() 함수를 사용
del fruits[0] # 인덱스로 삭제
fruits.remove('orange') # 값으로 삭제
last_fruit = fruits.pop() # 마지막 요소 제거하고 반환
리스트 삭제 방법들
my_list = [1, 2, 3, 4, 5]
# 방법 1: 리스트 내용을 모두 삭제해 빈 리스트로 만든다
my_list.clear() # 또는 my_list = []
print(my_list) # []
# 방법 2: 리스트에 None값을 넣어 빈 변수로 만든다
my_list = None
print(my_list) # None
# 방법 3: 변수를 삭제한다
del my_list
# print(my_list) # NameError 발생
리스트의 고급 활용법
1. 리스트 슬라이싱
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print(numbers[2:5]) # [2, 3, 4] - 2번부터 4번까지
print(numbers[:3]) # [0, 1, 2] - 처음부터 2번까지
print(numbers[7:]) # [7, 8, 9] - 7번부터 끝까지
print(numbers[::2]) # [0, 2, 4, 6, 8] - 2칸씩 건너뛰기
print(numbers[::-1]) # [9, 8, 7, 6, 5, 4, 3, 2, 1, 0] - 역순
2. 리스트 컴프리헨션 (List Comprehension)
# 1부터 10까지의 제곱수 만들기
squares = [x**2 for x in range(1, 11)]
print(squares) # [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
# 조건부 리스트 컴프리헨션
even_squares = [x**2 for x in range(1, 11) if x % 2 == 0]
print(even_squares) # [4, 16, 36, 64, 100]
3. 리스트 조작 함수들과 정렬
numbers = [3, 1, 4, 1, 5, 9, 2, 6]
# 리스트 조작 함수들
my_list = [1, 2, 3]
my_list.append(4) # 끝에 추가: [1, 2, 3, 4]
removed = my_list.pop() # 마지막 요소 제거하고 반환: 4
my_list.extend([5, 6]) # 여러 요소 추가: [1, 2, 3, 5, 6]
# 정렬: 리스트.sort()와 sorted(리스트)의 차이
original = [3, 1, 4, 1, 5]
original.sort() # 원본 리스트를 직접 수정
print(original) # [1, 1, 3, 4, 5]
original2 = [3, 1, 4, 1, 5]
sorted_list = sorted(original2) # 새로운 정렬된 리스트 반환
print(original2) # [3, 1, 4, 1, 5] (원본 유지)
print(sorted_list) # [1, 1, 3, 4, 5]
# 개수 세기
print(numbers.count(1)) # 2
# 위치 찾기
print(numbers.index(4)) # 2
# 리스트 합치기
list1 = [1, 2, 3]
list2 = [4, 5, 6]
combined = list1 + list2 # [1, 2, 3, 4, 5, 6]
list1.extend(list2) # list1에 list2 추가
4. 2차원 리스트
# 2차원 리스트에서 각 항목에 접근하려면 [0][0]처럼 첨자를 2개 사용해야 한다
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
print(matrix[0][0]) # 1 (첫 번째 행, 첫 번째 열)
print(matrix[1][2]) # 6 (두 번째 행, 세 번째 열)
# 리스트의 각 열의 크기를 다르게 생성할 수도 있다
irregular_matrix = [[1, 2], [3, 4, 5, 6], [7]]
print(irregular_matrix[1][3]) # 6
5. 리스트와 반복문 활용
# 리스트는 단독으로 사용하기보다는 대개 for문이나 while문과 함께 사용한다
fruits = ['apple', 'banana', 'cherry']
# for문과 함께 사용
for fruit in fruits:
print(f"I like {fruit}")
# 인덱스와 함께 사용
for i, fruit in enumerate(fruits):
print(f"{i}: {fruit}")
# while문과 함께 사용
i = 0
while i < len(fruits):
print(fruits[i])
i += 1
더보기
✅ 리스트 주요 메서드 정리표
메서드 | 설명 | 예시 |
append(x) | 리스트 끝에 요소 추가 | lst.append(5) |
extend(iter) | iterable 요소를 리스트에 추가 | lst.extend([4, 5]) |
insert(i, x) | i번째 위치에 x 삽입 | lst.insert(1, 100) |
remove(x) | x를 찾아 첫 번째 요소 삭제 | lst.remove(3) |
pop([i]) | i번째 요소 제거 후 반환 (기본: 마지막) | lst.pop() |
clear() | 모든 요소 삭제 | lst.clear() |
index(x) | x의 첫 번째 인덱스 반환 | lst.index(2) |
count(x) | x의 개수 반환 | lst.count(1) |
sort() | 리스트 정렬 (기본 오름차순) | lst.sort() |
sorted(iter) | 정렬된 리스트 반환 (원본 유지) | sorted(lst) |
reverse() | 리스트 순서를 반대로 뒤집음 | lst.reverse() |
copy() | 리스트의 얕은 복사본 생성 | lst2 = lst.copy() |
2. 튜플 (Tuple): 수정 불가, 읽기 전용 데이터 목록
기본 개념
- 정의: 리스트와 비슷하지만, 한 번 생성하면 값을 변경할 수 없는 자료구조
- 기호: 소괄호 ( ) 사용
- 특징:
- 순서(인덱스)가 있음
- 수정, 추가, 삭제 불가: immutable(불변) 자료형
- 중복 허용
- 다양한 데이터형 혼합 가능
튜플 생성과 특징
# 튜플은 소괄호()로 생성한다
point = (10, 20)
colors = ('red', 'green', 'blue')
mixed_tuple = (1, 'hello', 3.14, True)
# 항목이 하나인 튜플은 뒤에 쉼표(,)를 붙여야 한다
single = (42,) # 또는 42,
not_tuple = (42) # 이것은 그냥 정수 42
print(type(single)) # <class 'tuple'>
print(type(not_tuple)) # <class 'int'>
# 값 접근 (읽기만 가능해 읽기전용 자료를 저장할 때 사용한다)
print(point[0]) # 10
print(colors[-1]) # 'blue'
# 튜플의 값을 수정할 수 없다
# point[0] = 30 # TypeError: 'tuple' object does not support item assignment
튜플 연산과 변환
# 튜플의 덧셈 및 곱셈 연산도 가능하다
tuple1 = (1, 2, 3)
tuple2 = (4, 5, 6)
combined = tuple1 + tuple2 # (1, 2, 3, 4, 5, 6)
repeated = tuple1 * 3 # (1, 2, 3, 1, 2, 3, 1, 2, 3)
# 자료형 변환
my_list = [1, 2, 3, 4]
my_tuple = (1, 2, 3, 4)
# list(튜플) 함수는 튜플을 리스트로 변환
converted_list = list(my_tuple)
print(converted_list) # [1, 2, 3, 4]
# tuple(리스트) 함수는 리스트를 튜플로 변환
converted_tuple = tuple(my_list)
print(converted_tuple) # (1, 2, 3, 4)
# 튜플 자체는 del() 함수로 삭제할 수 있다
temp_tuple = (1, 2, 3)
del temp_tuple
# print(temp_tuple) # NameError 발생
튜플의 고급 활용법
1. 튜플 언패킹 (Unpacking)
# 좌표 언패킹
point = (10, 20)
x, y = point
print(f"x: {x}, y: {y}") # x: 10, y: 20
# 여러 값 동시 할당
person = ('Alice', 25, 'Engineer')
name, age, job = person
# 값 교환
a, b = 1, 2
a, b = b, a # a=2, b=1
2. 함수에서 여러 값 반환
def get_name_age():
return "Bob", 30
def calculate_stats(numbers):
return min(numbers), max(numbers), sum(numbers)/len(numbers)
name, age = get_name_age()
min_val, max_val, avg = calculate_stats([1, 2, 3, 4, 5])
3. 딕셔너리의 items()와 함께 사용
student_grades = {'Alice': 85, 'Bob': 92, 'Charlie': 78}
for name, grade in student_grades.items():
print(f"{name}: {grade}")
3. 딕셔너리 (Dictionary): 키-값 쌍의 집합
기본 개념
- 정의: 키(key)와 값(value)의 쌍으로 데이터를 저장하는 자료구조
- 기호: 중괄호 { } 사용, 키:값 쌍으로 구성
- 특징:
- 순서 없음(파이썬 3.7 이후 삽입 순서 유지)
- 키로 값에 접근 (인덱스 대신 키 사용)
- 수정, 추가, 삭제 가능: mutable
- 키는 중복 불가, 값은 중복 허용
딕셔너리 생성과 기본 조작
# 딕셔너리는 {} 중괄호로 묶어 구성
# 키(key)와 값(value)의 쌍으로 구성
student = {'name': 'Alice', 'age': 20, 'major': 'CS'}
empty_dict = {} # 또는 dict()
# '딕셔너리명[키] = 값' 형식으로 쌍을 추가할 수 있다
student['grade'] = 'A'
print(student) # {'name': 'Alice', 'age': 20, 'major': 'CS', 'grade': 'A'}
# 이미 존재하는 키를 사용하면 기존값이 변경
student['age'] = 21 # 기존 'age' 값 수정
print(student['age']) # 21
# 키는 유일해야 함 (중복된 키는 마지막 값으로 덮어짐)
duplicate_key_dict = {'name': 'Alice', 'name': 'Bob'}
print(duplicate_key_dict) # {'name': 'Bob'}
# 'del(딕셔너리명[키])' 형식으로 삭제 가능
del student['major']
print(student) # {'name': 'Alice', 'age': 21, 'grade': 'A'}
딕셔너리 값 접근 방법
student = {'name': 'Alice', 'age': 20, 'major': 'CS'}
# 딕셔너리명.get(키) 함수를 사용해 값에 접근
name1 = student['name'] # 'Alice'
name2 = student.get('name') # 'Alice'
# 딕셔너리명[키]와 딕셔너리명.get(키)는 결과가 같다
print(name1 == name2) # True
# 차이점: 없는 키 접근 시 동작
# 딕셔너리명[키]는 없는 키를 호출하면 오류가 나지만
try:
print(student['grade']) # KeyError 발생
except KeyError:
print("KeyError 발생!")
# 딕셔너리명.get(키)는 없는 키를 호출하면 None을 반환한다
grade = student.get('grade')
print(grade) # None
# 기본값 설정도 가능
grade_with_default = student.get('grade', 'N/A')
print(grade_with_default) # 'N/A'
딕셔너리 메서드들
student = {'name': 'Alice', 'age': 20, 'major': 'CS'}
# 딕셔너리명.keys()는 딕셔너리의 모든 키를 반환
keys = student.keys()
print(keys) # dict_keys(['name', 'age', 'major'])
# 출력 결과의 dict_keys가 보기 싫으면 list(딕셔너리명.keys()) 함수를 사용
keys_list = list(student.keys())
print(keys_list) # ['name', 'age', 'major']
# 딕셔너리명.values() 함수는 딕셔너리의 모든 값을 리스트로 만들어 반환
values = student.values()
print(values) # dict_values(['Alice', 20, 'CS'])
values_list = list(student.values())
print(values_list) # ['Alice', 20, 'CS']
# 딕셔너리명.items() 함수를 사용하면 키와 값의 쌍을 튜플 형태로 구현 가능
items = student.items()
print(items) # dict_items([('name', 'Alice'), ('age', 20), ('major', 'CS')])
# 딕셔너리 안에 해당 키가 있는지 없는지는 in을 사용해 확인할 수 있다
print('name' in student) # True
print('grade' in student) # False
print('Alice' in student.values()) # True
딕셔너리의 고급 활용법
1. 딕셔너리 메서드들
student = {'name': 'Alice', 'age': 20, 'major': 'CS'}
# 모든 키, 값, 키-값 쌍 가져오기
print(student.keys()) # dict_keys(['name', 'age', 'major'])
print(student.values()) # dict_values(['Alice', 20, 'CS'])
print(student.items()) # dict_items([('name', 'Alice'), ('age', 20), ('major', 'CS')])
# 딕셔너리 병합 (Python 3.9+)
defaults = {'grade': 'N/A', 'status': 'active'}
student = defaults | student # 또는 student.update(defaults)
2. 딕셔너리 컴프리헨션
# 숫자와 제곱수 딕셔너리
squares = {x: x**2 for x in range(1, 6)}
print(squares) # {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
# 조건부 딕셔너리 컴프리헨션
even_squares = {x: x**2 for x in range(1, 11) if x % 2 == 0}
print(even_squares) # {2: 4, 4: 16, 6: 36, 8: 64, 10: 100}
3. 중첩 딕셔너리 활용
# 학생 정보 관리
students = {
'Alice': {'age': 20, 'grade': 'A', 'subjects': ['Math', 'Physics']},
'Bob': {'age': 22, 'grade': 'B', 'subjects': ['Chemistry', 'Biology']}
}
# 중첩 딕셔너리 접근
print(students['Alice']['grade']) # 'A'
print(students['Bob']['subjects'][0]) # 'Chemistry'
더보기
✅ 딕셔너리 주요 메서드 정리표
메서드 설명 예시keys() | 모든 키 반환 | student.keys() |
values() | 모든 값 반환 | student.values() |
items() | (키, 값) 쌍 반환 | student.items() |
get(key) | 키의 값 반환 (없으면 None) | student.get("age") |
update({...}) | 값 수정 또는 키-값 추가 | student.update({"grade": 3}) |
pop(key) | 키-값 삭제 후 값 반환 | student.pop("major") |
clear() | 모든 항목 제거 | student.clear() |
in 연산자 | 키 존재 여부 확인 | 'name' in student |
setdefault() | 키가 없으면 추가, 있으면 그대로 반환 | student.setdefault("club", "AI Lab") |
4. 세트 (Set): 중복 없는 데이터 집합
기본 개념
- 정의: 중복 없는 데이터의 집합
- 기호: 중괄호 { } 사용, 값만 입력
- 특징:
- 순서 없음
- 중복 불가
- 수정(추가/삭제) 가능, 값 변경 불가
- 인덱싱 불가
세트의 기본 개념과 생성
# 세트(set)는 키만 모아놓은 딕셔너리의 특수한 형태이다
numbers = {1, 2, 3, 3, 4}
print(numbers) # {1, 2, 3, 4} - 중복 자동 제거
# 빈 세트를 만들 때는 s = set() 구문을 사용
# s = {} 구문을 쓰면 빈 딕셔너리로 인식
empty_set = set()
empty_dict = {}
print(type(empty_set)) # <class 'set'>
print(type(empty_dict)) # <class 'dict'>
# set() 함수는 리스트, 튜플, 딕셔너리들을 세트로 변경시켜준다
list_to_set = set([1, 2, 2, 3, 3, 4])
print(list_to_set) # {1, 2, 3, 4}
tuple_to_set = set((1, 2, 3, 3, 4))
print(tuple_to_set) # {1, 2, 3, 4}
dict_to_set = set({'a': 1, 'b': 2, 'c': 3}) # 키만 추출
print(dict_to_set) # {'a', 'b', 'c'}
# 리스트에서 중복 제거
list_with_duplicates = [1, 2, 2, 3, 3, 3, 4]
unique_numbers = list(set(list_with_duplicates))
print(unique_numbers) # [1, 2, 3, 4] (순서는 보장되지 않음)
세트의 집합 연산
# 집합 연산 (메서드와 연산자 두 가지 방법)
set1 = {1, 2, 3, 4}
set2 = {3, 4, 5, 6}
# 합집합 (union)
print(set1 | set2) # {1, 2, 3, 4, 5, 6}
print(set1.union(set2)) # {1, 2, 3, 4, 5, 6}
# 교집합 (intersection)
print(set1 & set2) # {3, 4}
print(set1.intersection(set2)) # {3, 4}
# 차집합 (difference)
print(set1 - set2) # {1, 2}
print(set1.difference(set2)) # {1, 2}
# 대칭차집합 (symmetric_difference)
print(set1 ^ set2) # {1, 2, 5, 6}
print(set1.symmetric_difference(set2)) # {1, 2, 5, 6}
# 세트 요소 추가/제거
my_set = {1, 2, 3}
my_set.add(4) # 요소 추가
my_set.remove(2) # 요소 제거 (없으면 오류)
my_set.discard(5) # 요소 제거 (없어도 오류 없음)
print(my_set) # {1, 3, 4}
더보기
✅ zip() 함수
- 여러 개의 iterable을 병렬로 묶어줌
- 주로 for문에서 많이 사용됨
names = ['Tom', 'Jane', 'Mike']
scores = [90, 85, 95]
for name, score in zip(names, scores):
print(f'{name}의 점수는 {score}점입니다.')
✅ 얕은 복사 vs 깊은 복사
구분 | 설명 | 예시 |
얕은 복사 | 참조만 복사하여 원본과 연결됨 | copy_list = original_list |
깊은 복사 | 객체 전체를 새롭게 복사하여 독립적인 객체 생성 | import copycopy.deepcopy(original_list) |
import copy
# 얕은 복사
a = [1, 2, [3, 4]]
b = a
b[2][0] = 99
print(a) # [1, 2, [99, 4]]
# 깊은 복사
c = copy.deepcopy(a)
c[2][0] = 3
print(a) # [1, 2, [99, 4]]
print(c) # [1, 2, [3, 4]]
5. 실전 활용 예제
예제 1: 학생 성적 관리 시스템
# 딕셔너리와 리스트를 활용한 성적 관리
class GradeManager:
def __init__(self):
self.students = {}
def add_student(self, name, *grades):
self.students[name] = list(grades)
def add_grade(self, name, grade):
if name in self.students:
self.students[name].append(grade)
def get_average(self, name):
if name in self.students and self.students[name]:
return sum(self.students[name]) / len(self.students[name])
return 0
def get_top_students(self, n=3):
averages = [(name, self.get_average(name)) for name in self.students]
return sorted(averages, key=lambda x: x[1], reverse=True)[:n]
# 사용 예시
gm = GradeManager()
gm.add_student('Alice', 85, 92, 78)
gm.add_student('Bob', 90, 88, 94)
gm.add_grade('Alice', 95)
print(f"Alice 평균: {gm.get_average('Alice'):.2f}")
print("상위 학생들:", gm.get_top_students())
예제 2: 단어 빈도 분석
def analyze_text(text):
# 단어 분리 및 소문자 변환
words = text.lower().replace(',', '').replace('.', '').split()
# 딕셔너리로 단어 빈도 계산
word_count = {}
for word in words:
word_count[word] = word_count.get(word, 0) + 1
# 가장 많이 사용된 단어들
sorted_words = sorted(word_count.items(), key=lambda x: x[1], reverse=True)
return {
'total_words': len(words),
'unique_words': len(word_count),
'most_common': sorted_words[:5],
'word_frequencies': word_count
}
text = "Python is great. Python is powerful. Programming with Python is fun."
result = analyze_text(text)
print(f"총 단어 수: {result['total_words']}")
print(f"고유 단어 수: {result['unique_words']}")
print("가장 자주 사용된 단어들:", result['most_common'])
6. 자료구조 비교 표
자료구조 | 기호 | 순서 | 중복 | 변경 | 인덱스/키 | 대표 메서드/연산 |
리스트 | [ ] | O | O | O | 인덱스 | append, pop, sort |
튜플 | ( ) | O | O | X | 인덱스 | count, index |
딕셔너리 | { } | X | 값O | O | 키 | keys, values, items |
세트 | { } | X | X | O | X | add, remove, union, intersection |
7. 성능 비교와 선택 기준
시간 복잡도 비교
- 리스트:
- 접근: O(1), 검색: O(n), 삽입/삭제: O(n)
- 튜플:
- 접근: O(1), 검색: O(n)
- 딕셔너리:
- 접근/삽입/삭제: 평균 O(1)
- 세트:
- 검색/삽입/삭제: 평균 O(1)
언제 어떤 자료구조를 써야 할까?
리스트 사용 시기:
- 순서가 중요한 데이터 저장
- 동일한 값이 여러 번 필요
- 데이터의 추가/수정/삭제가 빈번
- 인덱스로 빠른 접근이 필요
튜플 사용 시기:
- 변경되지 않아야 하는 데이터
- 함수에서 여러 값 반환
- 딕셔너리의 키로 사용 (immutable이므로)
- 좌표, 색상값 등 고정된 데이터
딕셔너리 사용 시기:
- 키-값 쌍으로 데이터 관리
- 빠른 검색이 필요
- 데이터에 의미있는 이름 부여
- 설정 정보, 매핑 데이터 저장
세트 사용 시기:
- 중복 제거가 필요
- 집합 연산 (합집합, 교집합 등) 수행
- 멤버십 테스트가 빈번
- 고유한 값들만 저장
8. 마무리
파이썬의 핵심 자료구조들은 각각 고유한 특성과 장점을 가지고 있습니다. 효율적인 파이썬 프로그래밍을 위해서는:
- 각 자료구조의 특성을 정확히 이해하고
- 상황에 맞는 적절한 선택을 하며
- 고급 기능들을 활용하여 코드를 간결하고 효율적으로 작성해야 합니다
이러한 자료구조들을 잘 활용하면 복잡한 데이터 처리도 간단하고 직관적으로 해결할 수 있으며, 파이썬의 진정한 힘을 경험할 수 있을 것입니다!
더보기
파이썬 자료구조 시험 대비 핵심 요약 📚
🎯 시험 출제 포인트 요약
1. 자료구조 기본 특징 (암기 필수!)
자료구조 | 기호 | 순서 | 중복 | 변경가능 | 접근방법 | 특징 |
리스트 | [ ] | ⭕ | ⭕ | ⭕ | 인덱스 | mutable, 다양한 데이터형 혼합 |
튜플 | ( ) | ⭕ | ⭕ | ❌ | 인덱스 | immutable, 읽기전용 |
딕셔너리 | { } | △ | 값⭕키❌ | ⭕ | 키 | 키-값 쌍, 키는 유일 |
세트 | { } | ❌ | ❌ | ⭕ | - | 중복제거, 집합연산 |
2. 시험 단골 문제 유형
⚠️ 자주 틀리는 포인트들
# 1. 빈 자료구조 생성
empty_list = [] # 리스트
empty_tuple = () # 튜플
empty_dict = {} # 딕셔너리
empty_set = set() # 세트 (주의: {}는 딕셔너리!)
# 2. 단일 요소 튜플
single_tuple = (5,) # 쉼표 필수!
# single_tuple = (5) # 이건 그냥 정수 5
# 3. 음수 인덱싱
lst = [1, 2, 3, 4, 5]
print(lst[-1]) # 5 (마지막)
print(lst[-2]) # 4 (뒤에서 두번째)
# 4. 딕셔너리 접근법 차이
student = {'name': 'Alice'}
print(student['name']) # 'Alice'
print(student.get('name')) # 'Alice'
print(student['age']) # KeyError 발생!
print(student.get('age')) # None 반환
📋 함수/메서드 완전 정리
리스트 메서드 (시험 필수!)
메서드 | 기능 | 예시 | 반환값 | 원본변경 |
append(x) | 끝에 요소 추가 | lst.append(5) | None | ⭕ |
insert(i, x) | i위치에 x 삽입 | lst.insert(0, 'first') | None | ⭕ |
remove(x) | 첫번째 x 제거 | lst.remove('apple') | None | ⭕ |
pop() | 마지막 요소 제거&반환 | item = lst.pop() | 제거된 요소 | ⭕ |
pop(i) | i위치 요소 제거&반환 | item = lst.pop(0) | 제거된 요소 | ⭕ |
index(x) | x의 첫번째 인덱스 | idx = lst.index('apple') | 인덱스 | ❌ |
count(x) | x의 개수 | cnt = lst.count(5) | 개수 | ❌ |
sort() | 정렬 (오름차순) | lst.sort() | None | ⭕ |
sort(reverse=True) | 내림차순 정렬 | lst.sort(reverse=True) | None | ⭕ |
reverse() | 순서 뒤집기 | lst.reverse() | None | ⭕ |
clear() | 모든 요소 제거 | lst.clear() | None | ⭕ |
copy() | 얕은 복사 | new_lst = lst.copy() | 새 리스트 | ❌ |
extend() | ||||
len() | ||||
sorted() |
⚡ 시험 TIP: sort() vs sorted() 구분!
lst = [3, 1, 4]
lst.sort() # 원본 변경, None 반환
new_lst = sorted(lst) # 원본 유지, 새 리스트 반환
튜플 메서드
메서드 | 기능 | 예시 | 반환값 |
count(x) | x의 개수 | tup.count(5) | 개수 |
index(x) | x의 첫번째 인덱스 | tup.index('apple') | 인덱스 |
💡 튜플 변환
tuple_to_list = list(tup) # 튜플 → 리스트
list_to_tuple = tuple(lst) # 리스트 → 튜플
딕셔너리 메서드 (시험 중요!)
메서드 | 기능 | 예시 | 반환값 | 원본변경 |
get(key) | 키의 값 반환 (없으면 None) | dic.get('name') | 값 또는 None | ❌ |
get(key, default) | 키의 값 반환 (없으면 기본값) | dic.get('age', 0) | 값 또는 기본값 | ❌ |
keys() | 모든 키 반환 | dic.keys() | dict_keys 객체 | ❌ |
values() | 모든 값 반환 | dic.values() | dict_values 객체 | ❌ |
items() | 키-값 쌍들 반환 | dic.items() | dict_items 객체 | ❌ |
pop(key) | 키 제거 & 값 반환 | val = dic.pop('name') | 제거된 값 | ⭕ |
clear() | 모든 항목 제거 | dic.clear() | None | ⭕ |
update(other) | 딕셔너리 병합 | dic.update({'age': 20}) | None | ⭕ |
⚡ 시험 단골: dic['key'] vs dic.get('key')
# 없는 키 접근 시
dic['nonexistent'] # KeyError 발생!
dic.get('nonexistent') # None 반환 (오류 없음)
세트 메서드
메서드 | 기능 | 예시 | 반환값 | 원본변경 |
add(x) | 요소 추가 | s.add(5) | None | ⭕ |
remove(x) | 요소 제거 (없으면 오류) | s.remove(5) | None | ⭕ |
discard(x) | 요소 제거 (없어도 오류 없음) | s.discard(5) | None | ⭕ |
pop() | 임의 요소 제거&반환 | item = s.pop() | 제거된 요소 | ⭕ |
clear() | 모든 요소 제거 | s.clear() | None | ⭕ |
집합 연산 메서드
메서드 | 연산자 | 기능 | 예시 |
union(other) | | | 합집합 | s1.union(s2) 또는 s1 | s2 |
intersection(other) | & | 교집합 | s1.intersection(s2) 또는 s1 & s2 |
difference(other) | - | 차집합 | s1.difference(s2) 또는 s1 - s2 |
symmetric_difference(other) | ^ | 대칭차집합 | s1.symmetric_difference(s2) 또는 s1 ^ s2 |
🔥 시험 출제 예상 문제 유형
1. 슬라이싱 (90% 출제!)
lst = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# 기본 슬라이싱
lst[2:5] # [2, 3, 4]
lst[:3] # [0, 1, 2]
lst[5:] # [5, 6, 7, 8, 9]
lst[:] # 전체 복사
# 간격 슬라이싱
lst[::2] # [0, 2, 4, 6, 8] (2칸씩)
lst[1::2] # [1, 3, 5, 7, 9] (1부터 2칸씩)
lst[::-1] # [9, 8, 7, 6, 5, 4, 3, 2, 1, 0] (역순)
lst[::-2] # [9, 7, 5, 3, 1] (역순으로 2칸씩)
2. 2차원 리스트 접근
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
matrix[0][0] # 1 (첫번째 행, 첫번째 열)
matrix[1][2] # 6 (두번째 행, 세번째 열)
matrix[-1][-1] # 9 (마지막 행, 마지막 열)
3. 컴프리헨션 (자주 출제!)
# 리스트 컴프리헨션
squares = [x**2 for x in range(5)] # [0, 1, 4, 9, 16]
evens = [x for x in range(10) if x % 2 == 0] # [0, 2, 4, 6, 8]
# 딕셔너리 컴프리헨션
square_dict = {x: x**2 for x in range(5)} # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
# 세트 컴프리헨션
unique_squares = {x**2 for x in range(-3, 4)} # {0, 1, 4, 9}
4. 자료구조 변환
# 문자열 → 리스트
list("hello") # ['h', 'e', 'l', 'l', 'o']
# 리스트 → 문자열
"".join(['h', 'e']) # "he"
# 중복 제거
unique_list = list(set([1, 2, 2, 3, 3])) # [1, 2, 3]
# 리스트 → 딕셔너리 (zip 사용)
keys = ['a', 'b', 'c']
values = [1, 2, 3]
dict(zip(keys, values)) # {'a': 1, 'b': 2, 'c': 3}
🎲 스택/큐 구현 (실습 문제 단골!)
스택 (LIFO - Last In First Out)
stack = []
# Push (삽입)
stack.append(1)
stack.append(2)
stack.append(3)
# Pop (제거)
top = stack.pop() # 3 (마지막에 들어간 것부터)
큐 (FIFO - First In First Out)
from collections import deque
queue = deque()
# Enqueue (삽입)
queue.append(1)
queue.append(2)
queue.append(3)
# Dequeue (제거)
front = queue.popleft() # 1 (먼저 들어간 것부터)
🚨 시험 직전 체크리스트
암기 필수 사항
- 빈 자료구조: [], (), {}, set()
- 단일 튜플: (5,) (쉼표 필수!)
- 음수 인덱싱: -1이 마지막 요소
- 딕셔너리 접근: dict['key'] vs dict.get('key')
- 집합 연산: |(합), &(교), -(차), ^(대칭차)
함수 vs 메서드 구분
# 함수 (새로운 객체 반환, 원본 유지)
sorted(lst) # 정렬된 새 리스트
list(tup) # 튜플을 리스트로 변환
set(lst) # 리스트를 세트로 변환
# 메서드 (원본 객체 변경)
lst.sort() # 원본 리스트 정렬
lst.append() # 원본 리스트에 추가
시간 복잡도 (고급 과정)
- 리스트: 인덱스 접근 O(1), 검색 O(n)
- 딕셔너리: 키 접근 O(1), 검색 O(1)
- 세트: 멤버십 테스트 O(1)
💡 마지막 당부
- 실제 코드 작성 연습: 이론만 외우지 말고 직접 타이핑해보기
- 에러 메시지 익히기: KeyError, IndexError 등 자주 나오는 에러들
- 예외 상황 체크: 빈 리스트에서 pop(), 없는 키 접근 등
- 출력 결과 예측: 코드 보고 출력값 맞추는 연습
🔥 시험 직전 마지막 점검: 이 요약본을 시험 30분 전에 한 번 더 훑어보세요!
728x90
반응형
'개발 공부 > Python' 카테고리의 다른 글
09_파이썬 함수와 모듈 마스터하기: 기본부터 심화까지 완벽 가이드! (0) | 2025.06.09 |
---|---|
08_파이썬 문자열 (String) 완전 정복하기! ✨ (1) | 2025.06.09 |
06_파이썬 반복문 완전 정복 (for, while, break, continue) (0) | 2025.06.09 |
05_파이썬 조건문 완전 정복! if 문으로 코드의 흐름을 제어해보자 (0) | 2025.06.09 |
04_파이썬 연산자 완전 정복! 종류부터 활용까지 총정리 (0) | 2025.06.09 |