1. 리스트 개요
1.1 리스트란?
여러개의 값을 하나의 변수에 순서대로 저장하는 자료형이다.
컨테이너 자료형으로 데이터 전처리 과정에서 핵심적으로 사용된다.
my_list = [1, 2, 3, 4, 5]
핵심 키워드
• 저장된 값에는 순서(index) 가 있다
• 여러 개의 값을 저장할 수 있다
• 서로 다른 자료형을 함께 저장할 수 있다
• 생성 이후에도 내용을 변경할 수 있다.
1.2 리스트의 변경 가능성 (Mutability)
리스트(List)는 변경 가능한 자료형이다.
이는 리스트가 한 번 생성된 이후에도, 리스트 객체 자체를 새로 만들지 않고 내부 요소를 직접 수정할 수 있음을 의미한다.
즉, 리스트는 같은 메모리 공간을 유지한 채 값이 바뀔 수 있는 객체이다.
2. 리스트 생성과 기본 사용법
2.1 리스트 생성 방법
# 1. 리스트 생성
my_list_empty = []
my_list_full = [1, 2, 3, 4, 5]
# 2. list()함수 사용
chars = list('hello')
# 3. 리스트의 기본 구조 츨력
print(my_list) # 출력: [1, 2, 3, 4, 5]
print(chars) # 출력: ['h', 'e', 'l', 'l', 'o']
# 4. 반복을 사용한 리스트 생성
numbers = []
for i in range(1, 6):
numbers.append(i)
print(numbers) # 출력: [1, 2, 3, 4, 5]
2.2 리스트 인덱싱(Indexing)
인덱싱이란 리스트에서 특정 위치의 요소 하나를 선택하는 방법이다.
사용 예시
cities = ["Seoul", "Busan", "Incheon"]
# 양의 인덱싱
print(cities[0]) # Seoul
# 음의 인덱싱
print(cities[-1]) # Incheon
2.3 리스트 슬라이싱(Slicing)
리스트의 원하는 부분만 잘라서 사용하는 방법이다.
# 기본 형태
리스트[start : stop : step]
• start: 슬라이싱을 시작할 인덱스 (포함).
• stop: 슬라이싱을 종료할 인덱스 (미포함).
• step: 요소를 건너뛰는 간격.
사용 예시
cities = ["Seoul", "Busan", "Incheon", "Gwangju", "Daejeon"]
sub = cities[1:4]
print(sub)
# 출력: ['Busan', 'Incheon', 'Gwangju']
3. 리스트의 다양한 메소드
파이썬은 리스트를 조작하기 위한 다양한 내장 메소드를 제공한다.
3.1 append / insert / extend (요소의 추가)
모두 리스트에 새로운 요소를 추가하지만, 추가되는 위치와 방식이 서로 다르다.
my_list.append(6)
my_list.insert(2, 10)
my_list.extend([7, 8, 9])
• append - 리스트에 하나의 값(요소) 을 맨 뒤에 추가
• insert - 기존 순서를 유지하면서, 지정한 위치(index) 에 값을 삽입 (이때 기존 값들은 오른쪽으로 한 칸씩 밀린다 )
• extend- 여러 개의 값을 풀어서 추가 → “리스트와 리스트를 이어 붙인다”란 개념으로 접근
3.2 remove / pop / clear (요소의 제거)
리스트에서 요소를 제거하는 방식은 기준이 값인지, 위치인지에 따라 나뉜다.
my_list.remove(3)
popped_value = my_list.pop(5)
my_list.clear()
• remove - 값을 기준으로 첫 번째로 일치하는 요소를 제거
• pop - 지정한 인덱스의 요소를 제거하고 그 요소를 반환한다. 반환 인덱스를 지정하지 않으면 마지막 요소를 제거
• clear - 모든 요소를 제거
3.3 index / count ( 요소 검색 및 개수 세기 )
리스트를 조회하는 용도이며, 리스트를 변경하지 않는다.
my_list.index(4)
my_list.count(7)
• index - 요소의 인덱스를 반환. 특정 값이 처음 등장하는 위치를 알려준다
• count - 요소의 개수를 반환. 특정 값이 몇 번 등장하는지 세어준다
요소가 없을 때 발생하는 문제
3.4 sort / reverse ( 정렬 )
리스트의 순서를 변경한다.
my_list.sort()
my_list.reverse()
• sort - 리스트의 요소를 오름차순으로 정렬
• reverse - 리스트의 요소 순서를 반대로 뒤집는다
원본 리스트 변경 여부
sort, reverse는 모두 새 리스트를 만들지 않고 기존 리스트를 직접 수정한다.
따라서 정렬 전 상태가 필요하다면 복사본을 사용해야 한다
3.5 (len/ in, not in )리스트 길이와 포함 여부
numbers = [1, 3, 5, 7]
print(len(numbers)) # 4 → 리스트의 길이 확인
print(3 in numbers) # True → 3이 리스트에 포함되어 있음
print(10 not in numbers) # True → 10은 리스트에 포함되어 있지 않음
• len - 리스트에 들어 있는 요소의 개수를 반환한다. 만약 리스트가 비어 있으면 0을 반환한다.
• in, not in - 특정 값이 리스트에 포함되어 있는지 확인한다. 결과는 True 또는 False로 반환된다
4. 리스트 연산과 결합
연산자를 사용해 출력 결과를 바꿀수도 있다.
list1 = [1, 2, 3]
list2 = [4, 5, 6]
result = list1 + list2
print(result) # 출력: [1, 2, 3, 4, 5, 6]
print(list1*2) # 출력: [1, 2, 3, 1, 2, 3]
5. 리스트와 반복문
5.1 for문을 이용한 리스트 순회
리스트의 각 요소에 접근하거나 처리하기 위해 반복문을 사용할 수 있다
fruits = ['apple', 'banana', 'cherry']
for fruit in fruits:
print(fruit, end = ' ')
# 출력: apple banana cherry
인덱스와 함께 반복할수도 있다.
# enumerate : 인덱스와 값을 함께 불러올 수 있습니다.
for index, value in enumerate(fruits):
print(f'인덱스 {index}: {value}')
6. 리스트 컴프리헨션 (List Comprehension)
6.1 리스트 컴프리헨션의 기본 구조
기존 for문 + 조건문 패턴을 한 줄로 표현해 간결하고 효율적인 방법으로 새로운 리스트를 생성하는 문법이다.
[표현식 for 변수 in 반복가능객체]
[표현식 for 변수 in 반복가능객체 if 조건]
읽는 순서
- for x in range(...)
- if 조건
- 맨 앞의 표현식
# 일반적인 for문
result = []
for x in range(1, 6):
result.append(x)
# 리스트 컴프리헨션
result = [x for x in range(1, 6)]
실행 순서 (Line by Line)
| 1. range(1, 6) 생성 2. 첫 값 x = 1 3. 표현식 x 실행 → 1 4. 리스트에 추가 5. 반복 종료까지 반복 |
7. 중첩 리스트 (Nested List)
7.1 2차원 리스트 개념
리스트 안에 또 하나의 리스트를 넣을수도 있다
matrix = [
[1, 2],
[3, 4],
[5, 6]
]
for row in matrix:
for value in row:
print(value) # 출력: 1 2 3 4 5 6
개념적으로 보면
바깥 for문 → “행 단위 접근”
안쪽 for문 → “해당 행의 요소 접근”
리스트 컴프리헨션에서 중첩이 등장할 때도 이 순서가 그대로 유지된다.
⭐ 중첩 리스트는 항상 밖에서부터 안쪽을 천천히 까보면서 들어가야 한다. ⭐
8. 리스트 복사와 메모리 관리
파이썬에서 리스트는 값 자체가 아니라 객체(Object) 로 메모리에 저장된다.
변수는 이 객체를 직접 담는 것이 아니라, 객체가 저장된 메모리 위치를 가리키는 참조(reference) 를 가진다.
| 메모리 어딘가: [1, 2, 3] ← 실제 리스트 객체 a ─────────▶ [1, 2, 3] |
a = [1, 2, 3] 은 [a 안에 리스트가 들어 있다]가 아닌 [a는 리스트가 있는 위치를 가리킨다]로 이해하는것이 옳다.
짚고 넘어가기: 참조 복사란?
a = [1, 2, 3]
b = a
| a ─────▶ [1, 2, 3] b ─────▶ [1, 2, 3] |
리스트 객체는 하나이고, 이름표만 두 개(a, b)인 상태다.
따라서 어느 한 쪽에서 리스트를 수정하면, 같은 객체를 가리키는 다른 변수에서도 변경이 보인다.
이것이 b.append()를 했는데 a도 바뀌는 이유다.
8.1 얕은 복사 (Shallow Copy)
얕은 복사는 겉에 있는 리스트만 새로 만들고, 리스트 안에 들어 있는 객체들은 그대로 공유하는 복사 방식이다.
original = [1, 2, [3, 4]]
shallow = original[:]
바깥 리스트는 서로 다른 객체지만 내부 리스트 [3, 4] 는 같은 객체를 공유한다.
따라서 내부 리스트를 수정하면 두 리스트 모두 영향을 받는다.
얕은 복사는 1차원 리스트에서는 큰 문제가 없지만, 중첩 리스트에서는 매우 쉽게 버그의 원인이 된다.
발생하는 경우
다음 방법들은 모두 얕은 복사이다.
• 슬라이싱 [:]
• list()
• list.copy()
• copy.copy()
8.2 깊은 복사 (Deep Copy)
깊은 복사는 바깥 리스트뿐만 아니라 내부의 모든 하위 객체까지 전부 새로 복사한다.
즉, 복사본과 원본은 어느 수준에서도 객체를 공유하지 않는다.
import copy
original = [1, 2, [3, 4]]
deep = copy.deepcopy(original)
겉과 속 모두 완전히 독립적이다.
8.3 리스트와 메모리 관점에서의 이해
1) 변수와 객체의 관계
• 변수는 값이 아니라 객체의 주소를 가리킨다
• 여러 변수가 하나의 객체를 가리킬 수 있다
• 복사”와 “참조 공유”를 구분하지 않으면 예기치 않은 결과가 발생한다
8.4 표로 보기
| 구분 | 얕은 복사 | 깊은 복사 |
| 바깥 객체 | 새로 생성 | 새로 생성 |
| 내부 객체 | 공유 | 전부 새로 생성 |
| 독립성 | 부분적 | 완전 |
| 중첩 리스트 | 위험 | 안전 |
어렵다면 이렇게 생각하기
안에 리스트가 있나?
없다 → 얕은 복사 OK
있다 → 깊은 복사 필요
9. 리스트 실용 예제
9.1 리스트의 실용 예제
중복 제거
리스트에는 같은 값이 여러 번 들어갈 수 있다. 만약 중복을 제거한 값이 필요한 경우... set을 사용한다.
수도코드로 보기
| 숫자가 여러 개 들어 있는 리스트를 준비한다 리스트를 set으로 변환하여 중복을 제거한다 다시 리스트로 변환한다 결과를 출력한다 |
numbers = [1, 2, 2, 3, 4, 4, 5]
unique_numbers = list(set(numbers))
print(unique_numbers)
실행 순서 (Line by Line)
| 1. numbers 리스트 생성 # [1, 2, 2, 3, 4, 4, 5] 2. set(numbers) 실행 # {(1, 2, 3, 4, 5) 3. 중복된 2,4는 하나만 남는다. (순서 보장 x) 4. list(...) 실행 # [1, 2, 3, 4, 5] |
9.2 컴프리헨션을 사용한 조건부 리스트
1부터 20까지 숫자 중 3의 배수만 리스트로 만들기
수도코드로 보기
| 1부터 20까지 숫자를 하나씩 확인한다 해당 숫자가 3으로 나누어 떨어지면 리스트에 추가한다 |
multiples_of_three = [x for x in range(1, 21) if x % 3 == 0]
print(multiples_of_three)
#출력: [3, 6, 9, 12, 15, 18]
실행 순서 (Line by Line)
| 1. range(1, 21) 생성 2. 값 x의 몫이 0이면 참(값을 반환), 0아 아니면 거짓 (다음 x 값으로) 3. 리스트 출력 |
9.3 2차원 리스트에서의 특정 조건의 요소 찾기
수도코드로 보기
| 각 행(row)을 하나씩 가져온다 행 안의 각 요소(item)를 하나씩 확인한다 item이 30보다 크면 결과 리스트에 추가한다 |
matrix = [
[5, 10, 15],
[20, 25, 30],
[35, 40, 45]
]
result = [item for row in matrix for item in row if item > 30]
print(result)
# 출력 [35, 40, 45]
실행 순서 (Line by Line)
| 1. 첫 번째 행 검사 [5, 10, 15] 2. 두번째 행 검사 [20. 25. 30] 3 세 번째 행 검사 [35, 40, 45] (모두 30을 초과했기 때문에 리스트에 반환) 4. 출력 |
10. 오늘 학습한 내용 정리
- 리스트의 개념과 특징
- 리스트 인덱싱과 슬라이싱 동작
- 리스트 메서드를 통한 내부 동작 방식
- 반복문과 리스트 컴프리헨션
- 중첩 리스트와 복사 개념
- 데이터 전처리에 활용되는 실용 패턴
'G.파이썬 > 파이썬 기초 복습' 카테고리의 다른 글
| [Python] 함수와 모듈 (0) | 2026.01.15 |
|---|---|
| [Python] 자료형 STEP 3. 딕셔너리 (0) | 2026.01.14 |
| [Python] 자료형 STEP 2. 튜플 (0) | 2026.01.14 |
| [Python] 조건문과 반복문 (0) | 2026.01.12 |
| [Python] 입출력과 변수형 (0) | 2026.01.12 |
