파이썬에서 학생 이름이나 상품 가격처럼 여러 값을 한꺼번에 다루려면 리스트를 사용합니다. 리스트는 값을 넣는 것에서 끝나지 않고, 필요한 위치의 값을 읽고 바꾸거나 추가, 삭제, 정렬할 수 있습니다.
이 글은 리스트를 처음 접한 분이 생성 → 조회 → 수정 → 삭제 → 정렬 → 반복 순서로 직접 실행해 볼 수 있게 구성했습니다. 특히 append()와 extend(), remove()와 pop()처럼 이름은 비슷하지만 쓰임이 다른 기능을 구분해 보겠습니다.

테스트 환경
아래 예제는 다음 환경에서 직접 실행했습니다.
작성 및 실행 확인 : 2026년 7월 30일
운영체제 : Windows
로컬 Python : Python 3.9.13
공식 문서 확인 : Python 3.14.6 문서
이 글에서 사용하는 기본 리스트 문법과 메서드는 Python 3 계열에서 같은 방식으로 사용할 수 있습니다.
리스트는 여러 값을 순서대로 저장한다
리스트는 대괄호 [] 안에 값을 쉼표로 구분해 만듭니다.
students = ["김철수", "이영희", "박민수", "최지은", "홍길동"]
문자열뿐 아니라 숫자, 논리값, 실수처럼 자료형이 다른 값도 한 리스트에 넣을 수 있습니다.
data = [10, "Python", True, 3.14]
빈 리스트는 [] 또는 list()로 만들 수 있습니다.
items = []
numbers = list()

실제 프로그램에서는 같은 의미의 값을 모아 두는 경우가 많습니다. 과일 이름은 과일 이름끼리, 점수는 점수끼리 넣으면 반복 처리와 정렬이 쉬워집니다.
인덱스는 0부터 시작한다
리스트의 위치 번호를 인덱스라고 합니다. 첫 번째 값의 인덱스가 1이 아니라 0이라는 점이 처음 배울 때 가장 헷갈리기 쉽습니다.
fruits = ["사과", "바나나", "포도"]
print(fruits[0])
print(fruits[1])
print(fruits[-1])
실행 결과입니다.
사과
바나나
포도
음수 인덱스는 뒤에서부터 셉니다. fruits[-1]은 마지막 값, fruits[-2]는 뒤에서 두 번째 값입니다.

리스트의 일부만 가져올 때는 슬라이싱을 사용합니다.
print(fruits[0:2])
print(fruits[1:])
['사과', '바나나']
['바나나', '포도']
fruits[0:2]에서 끝 인덱스 2는 포함되지 않습니다. 따라서 인덱스 0과 1의 값만 가져옵니다. 전체 요소 개수는 len(fruits)로 확인할 수 있습니다.
print(len(fruits))
3
리스트를 만들고 출력해 보기
다음 코드는 리스트 전체와 특정 값, 슬라이싱 결과를 한 번에 확인합니다.
fruits = ["사과", "바나나", "포도"]
mixed = [10, "Python", True, 3.14]
print("전체:", fruits)
print("첫 번째:", fruits[0])
print("마지막:", fruits[-1])
print("슬라이싱:", fruits[0:2])
print("길이:", len(fruits))
print("혼합 자료형:", mixed)
직접 실행한 결과입니다.
전체: ['사과', '바나나', '포도']
첫 번째: 사과
마지막: 포도
슬라이싱: ['사과', '바나나']
길이: 3
혼합 자료형: [10, 'Python', True, 3.14]

값 추가는 append, extend, insert로 구분한다
append()는 값 하나를 리스트 맨 뒤에 추가합니다.
fruits = ["사과", "바나나"]
fruits.append("포도")
print(fruits)
['사과', '바나나', '포도']
여러 값을 이어 붙이려면 extend()를 사용합니다.
fruits.extend(["수박", "복숭아"])
print(fruits)
['사과', '바나나', '포도', '수박', '복숭아']
원하는 위치에 넣을 때는 insert(인덱스, 값) 형태로 작성합니다.
fruits.insert(1, "딸기")
print(fruits)
['사과', '딸기', '바나나', '포도', '수박', '복숭아']

append(["수박", "복숭아"])처럼 리스트를 전달하면 두 값이 따로 추가되는 것이 아니라, 리스트 하나가 중첩된 요소로 들어갑니다. 여러 요소를 각각 추가하려는 상황이라면 extend()가 맞습니다.
인덱스로 기존 값 수정하기
이미 들어 있는 값은 해당 인덱스에 새 값을 대입해 바꿉니다.
fruits = ["사과", "바나나"]
fruits[1] = "딸기"
print(fruits)
['사과', '딸기']
존재하지 않는 위치에 대입해서 새 요소를 만들 수는 없습니다. 맨 뒤에 새 값을 넣을 때는 fruits[len(fruits)] = "포도"가 아니라 append()를 사용해야 합니다.
삭제는 값인지 위치인지 먼저 정한다
remove()는 지정한 값과 같은 첫 번째 요소를 삭제합니다.
fruits = ["사과", "바나나", "포도", "바나나"]
fruits.remove("바나나")
print(fruits)
['사과', '포도', '바나나']
같은 값이 두 개여도 첫 번째 "바나나"만 없어졌습니다.
pop()은 인덱스로 삭제하며, 삭제한 값을 돌려줍니다. 인덱스를 생략하면 마지막 요소를 삭제합니다.
removed = fruits.pop(1)
print("삭제한 값:", removed)
print("남은 리스트:", fruits)
삭제한 값: 포도
남은 리스트: ['사과', '바나나']
모든 요소만 비우고 리스트 변수는 그대로 두려면 clear()를 사용합니다.
fruits.clear()
print(fruits)
[]

정리하면 값으로 찾아 지울 때는 remove(), 위치로 지우거나 삭제된 값을 다시 써야 할 때는 pop()이 자연스럽습니다.
sort는 원본을 바꾸고 sorted는 새 리스트를 만든다
숫자 리스트를 오름차순으로 바꿀 때는 sort()를 사용합니다.
numbers = [5, 1, 9, 3]
numbers.sort()
print(numbers)
[1, 3, 5, 9]
내림차순은 reverse=True를 전달합니다.
numbers.sort(reverse=True)
print(numbers)
[9, 5, 3, 1]
sort()는 리스트 자체를 바꾸고 반환값은 None입니다. 원본을 유지한 채 정렬된 새 리스트가 필요하면 sorted()를 사용합니다.
numbers = [5, 1, 9, 3]
ascending = sorted(numbers)
print("원본:", numbers)
print("정렬 결과:", ascending)
원본: [5, 1, 9, 3]
정렬 결과: [1, 3, 5, 9]
단순히 현재 순서를 반대로 만들 때는 reverse()를 사용합니다. 정렬과 뒤집기는 다르므로, 무작위 순서를 내림차순으로 만들고 싶다면 sort(reverse=True)를 사용해야 합니다.

숫자와 문자열처럼 서로 바로 비교할 수 없는 자료형이 섞인 리스트는 기본 sort()로 정렬할 때 TypeError가 발생할 수 있습니다.
in과 for문으로 값을 확인하고 반복한다
리스트에 특정 값이 있는지는 in으로 확인합니다.
fruits = ["사과", "바나나", "포도"]
print("사과" in fruits)
print("수박" in fruits)
True
False
값을 하나씩 꺼낼 때는 for문을 사용합니다.
for fruit in fruits:
print(fruit)
사과
바나나
포도
인덱스와 값을 함께 써야 한다면 enumerate()가 편합니다.
for index, value in enumerate(fruits):
print(index, value)
0 사과
1 바나나
2 포도

for문의 기본 구조가 아직 익숙하지 않다면 Python for문 사용법 : range 반복문과 리스트 반복 예제를 먼저 실행해 보셔도 좋습니다.
리스트 복사는 같은 참조와 새 리스트를 구분한다
다음 코드는 복사처럼 보이지만 두 변수가 같은 리스트를 가리킵니다.
a = [1, 2, 3]
b = a
a.append(4)
print(b)
[1, 2, 3, 4]
a만 수정했는데 b도 바뀐 것처럼 보입니다. 실제로는 두 변수가 같은 리스트를 가리키기 때문입니다.
별도의 리스트를 만들려면 copy() 또는 전체 슬라이싱을 사용합니다.
b = a.copy()
# 또는
b = a[:]
두 방법은 얕은 복사입니다. 리스트 안에 또 다른 리스트가 들어 있는 중첩 구조까지 완전히 분리해야 한다면 copy.deepcopy()가 필요하지만, 처음에는 일반 리스트의 copy()부터 정확히 구분해 두면 됩니다.
초보자가 자주 만나는 오류 3가지
IndexError : 범위를 벗어난 인덱스
요소가 3개인 리스트의 마지막 인덱스는 2입니다.
fruits = ["사과", "바나나", "포도"]
print(fruits[3])
IndexError: list index out of range
마지막 값을 가져오려면 fruits[2] 또는 fruits[-1]을 사용합니다.
TypeError : append에 값을 두 개 전달
append()는 한 번에 인수 하나만 받습니다.
fruits.append("딸기", "복숭아")
두 값을 각각 추가하려면 다음과 같이 작성합니다.
fruits.extend(["딸기", "복숭아"])
ValueError : remove할 값이 없음
리스트에 없는 값을 remove()로 삭제하면 ValueError가 발생합니다.
fruits.remove("수박")
값이 있을 때만 삭제하려면 먼저 in으로 확인합니다.
if "수박" in fruits:
fruits.remove("수박")

자주 쓰는 리스트 기능 한눈에 보기
| 기능 | 설명 | 예시 |
|---|---|---|
append() |
맨 뒤에 값 하나 추가 | fruits.append("사과") |
extend() |
여러 요소를 이어 붙임 | fruits.extend(["사과", "포도"]) |
insert() |
지정 위치에 값 추가 | fruits.insert(1, "바나나") |
remove() |
같은 값을 찾아 첫 번째 요소 삭제 | fruits.remove("사과") |
pop() |
지정 위치 또는 마지막 요소 삭제 후 반환 | fruits.pop() |
clear() |
모든 요소 삭제 | fruits.clear() |
sort() |
원본 리스트 정렬 | numbers.sort() |
reverse() |
현재 순서 뒤집기 | fruits.reverse() |
copy() |
얕은 복사본 생성 | fruits.copy() |
len() |
요소 개수 확인 | len(fruits) |

처음에는 모든 메서드를 외우기보다 append()와 extend()의 차이, remove()와 pop()의 삭제 기준, sort()가 원본을 바꾼다는 점부터 직접 실행해 보는 것이 좋습니다. 그다음 for문과 enumerate()를 연결하면 리스트에 저장한 값을 실제 프로그램에서 순서대로 처리할 수 있습니다.
같이 보면 좋은 글
- VSCode에서 Python 실행하는 방법 : 터미널, Run 버튼, 디버그 차이
- Python input 사용법 : 문자열과 숫자 입력받기 예제
- Python for문 사용법 : range 반복문과 리스트 반복 예제
참고 문서
'IT프로그래밍 > 파이썬' 카테고리의 다른 글
| 파이썬 변수 기초 : 값에 이름을 붙이면 무엇이 편해질까 (0) | 2026.08.07 |
|---|---|
| 파이썬 자료형 기초 : 숫자 10과 문자열 '10'은 왜 다를까 (0) | 2026.08.05 |
| 파이썬 코드 실행 순서 : 위에서 아래로 읽는 첫 번째 원리 (0) | 2026.08.04 |
| 파이썬 함수 만들기 : def 정의부터 매개변수와 return까지 (0) | 2026.07.31 |
| Python Install Manager 사용법 : Python 3.14 처음 설치부터 실행까지 (0) | 2026.07.20 |
| Python PATH 설정 확인 방법 : python 명령어가 인식되지 않을 때 (0) | 2026.07.12 |
| Python if문 사용법 : 조건문 예제와 비교 연산자 (0) | 2026.07.08 |
| Python while문 사용법 : 조건 반복문과 break 예제 (0) | 2026.07.06 |
댓글