# 파이썬 리스트(list): 메서드, 슬라이싱, 정렬, append, 튜플과 집합

URL: https://skillaria.top/ko/guides/python/python-lists

파이썬 리스트(list)는 대괄호로 묶은 순서가 있는 변경 가능한 자료형입니다. 예: [250, 1200, 99]. append로 끝에 추가하고, insert와 remove로 넣고 빼며, 슬라이싱으로 일부를 잘라내고, sort로 정렬합니다. sort는 원본을 정렬하고 None을 반환하며, sorted는 정렬된 새 리스트를 반환합니다.

파이썬 리스트(`list`)는 대괄호로 묶은 값들의 순서 있는 모음이며, 내용을 바꿀 수 있습니다. 끝에 원소를 추가하고, 중간에 끼워 넣고, 지우고, 정렬할 수 있습니다. 파이썬에서 가장 많이 쓰는 컬렉션으로, 파일의 줄, 한 달의 지출, API 응답 등 거의 모든 데이터가 리스트에서 시작합니다. 이 글에서는 리스트를 만드는 법, 메서드, 슬라이싱, 정렬, 리스트 컴프리헨션, 복사를 차례로 살펴보고, 마지막으로 튜플과 집합을 설명합니다.

## 파이썬 리스트란

리스트는 원소를 넣은 순서대로 보관하고, 인덱스는 0부터 셉니다. 한 리스트에 서로 다른 타입의 값을 넣을 수도 있지만, 실제로는 같은 종류의 데이터를 담는 경우가 대부분입니다.

```
amounts = [250, 1200, 99]
print(amounts[0])     # 250 — 첫 번째 원소
print(amounts[-1])    # 99 — 마지막 원소
amounts[1] = 1300     # 리스트는 변경할 수 있습니다
print(len(amounts))   # 3 — 길이
```

리스트의 길이는 `len()` 함수로 구합니다. 존재하지 않는 인덱스에 접근하면 `IndexError: list index out of range`가 발생합니다.

## 리스트 만들기

```
empty = []                       # 빈 리스트
also_empty = list()              # list 함수로 만들기
nums = [1, 2, 3]
chars = list("abc")              # ['a', 'b', 'c']
digits = list(range(5))          # [0, 1, 2, 3, 4]
zeros = [0] * 4                  # [0, 0, 0, 0]
```

`list()` 함수는 반복 가능한 객체를 리스트로 바꿔 줍니다. 문자열, `range`, 집합, 딕셔너리의 키 등이 해당합니다.

## append와 다른 리스트 메서드

`append`는 원소 하나를 리스트 끝에 추가합니다. 파이썬에서 가장 자주 쓰는 메서드입니다. 리스트 자체를 바꾸고 `None`을 반환합니다.

```
amounts = [250, 1200]
amounts.append(450)          # [250, 1200, 450]
amounts.extend([10, 20])     # [250, 1200, 450, 10, 20]
amounts.insert(0, 5)         # [5, 250, 1200, 450, 10, 20]
amounts.remove(1200)         # 처음 나오는 값 1200을 삭제
last = amounts.pop()         # 20 — 마지막 원소를 삭제하고 반환
```

흔한 실수가 있습니다. `a.append([10, 20])`은 숫자 두 개가 아니라 리스트 하나를 원소로 추가합니다. 여러 원소를 한꺼번에 넣으려면 `extend`를 쓰세요.

| 메서드 | 하는 일 |
| --- | --- |

| `append(x)` | x를 끝에 추가 |

| `extend(iter)` | 시퀀스의 모든 원소를 추가 |

| `insert(i, x)` | 인덱스 i 앞에 x 삽입 |

| `remove(x)` | 처음 나오는 x를 삭제 (없으면 ValueError) |

| `pop(i=-1)` | 인덱스의 원소를 삭제하고 반환 |

| `index(x)` | 처음 나오는 x의 인덱스 |

| `count(x)` | x가 나온 횟수 |

| `sort()` | 제자리에서 정렬 |

| `reverse()` | 제자리에서 뒤집기 |

| `copy()` | 얕은 복사 |

| `clear()` | 모두 비우기 |

인덱스로 원소를 지우거나 범위를 지울 때는 `del` 문도 씁니다: `del a[0]`, `del a[1:3]`. 리스트와 함께 자주 쓰는 내장 함수는 `len`, `sum`, `min`, `max`, `sorted`, `reversed`, `enumerate`, `zip`입니다.

## 파이썬 슬라이싱

슬라이스 `a[start:stop:step]`은 리스트의 일부를 가져옵니다. `start`는 포함하고, `stop`은 포함하지 않으며, `step`만큼 건너뜁니다. 생략할 수 있는 부분은 생략하면 됩니다. 슬라이스는 항상 새 리스트를 반환합니다.

```
a = [0, 1, 2, 3, 4, 5]
print(a[1:4])     # [1, 2, 3]
print(a[:2])      # [0, 1] — 앞의 두 개
print(a[-2:])     # [4, 5] — 뒤의 두 개
print(a[::2])     # [0, 2, 4] — 두 칸씩
print(a[::-1])    # [5, 4, 3, 2, 1, 0] — 뒤집은 리스트
print(a[:])       # 전체 복사본
```

인덱스와 달리, 리스트 범위를 벗어난 슬라이스는 오류를 내지 않습니다. `a[10:20]`은 그냥 `[]`를 반환합니다. 슬라이스에 값을 대입해 일부를 바꿀 수도 있습니다: `a[1:3] = ["x", "y", "z"]`.

### 문자열 슬라이싱

슬라이싱은 문자열과 튜플 같은 모든 시퀀스에서 같은 방식으로 동작합니다.

```
s = "Python 3.15"
print(s[:6])      # Python
print(s[-4:])     # 3.15
print(s[::-1])    # 51.3 nohtyP
```

문자열은 슬라이스로 바꿀 수 없습니다. 문자열은 변경할 수 없으므로 슬라이스는 새 문자열을 만듭니다.

## 리스트 정렬: sort와 sorted

초보자가 가장 많이 헷갈리는 부분입니다. `sort` 메서드는 리스트 안의 원소를 바로 재배열하고 `None`을 반환합니다. `sorted` 함수는 원본을 건드리지 않고 정렬된 새 리스트를 반환합니다.

```
amounts = [250, 1200, 99]
amounts.append(450)
print(sorted(amounts))     # [99, 250, 450, 1200] — 새 복사본
print(amounts)             # [250, 1200, 99, 450] — 원본은 그대로

result = amounts.sort()    # 제자리에서 정렬
print(result, amounts)     # None [99, 250, 450, 1200]
```

그래서 '왜 None이 나오지?'라는 고전적인 문제가 생깁니다. `a = a.sort()`라고 쓰면 리스트가 `None`으로 덮어씌워집니다. `a.sort()`로 쓰거나 `a = sorted(a)`로 쓰세요.

### key 인수와 내림차순

두 방식 모두 `key`와 `reverse` 인수를 받습니다. `key`는 원소를 비교할 기준 값을 계산하는 함수입니다.

```
words = ["커피", "택시요금", "구독"]
print(sorted(words, key=len))               # ['커피', '구독', '택시요금']
print(sorted(["bob", "Alice", "carl"], key=str.lower))  # ['Alice', 'bob', 'carl']
print(sorted([3, 1, 2], reverse=True))      # [3, 2, 1]

expenses = [("식비", 650), ("영화", 120), ("교통", 300)]
expenses.sort(key=lambda e: e[1])           # 금액 기준
```

파이썬의 정렬은 안정적(stable)입니다. 키가 같은 원소는 원래 순서를 유지합니다. 차이는 적용 범위에도 있습니다. `sorted`는 문자열, 딕셔너리, 집합 등 모든 반복 가능한 객체에 쓸 수 있지만, `sort` 메서드는 리스트에만 있습니다.

## 리스트 뒤집기

뒤집는 방법은 세 가지이며, 동작이 서로 다릅니다.

- `a.reverse()` — 제자리에서 뒤집고 `None`을 반환합니다.
- `a[::-1]` — 뒤집은 새 리스트를 만듭니다.
- `reversed(a)` — 필요할 때 값을 만드는 이터레이터입니다. 반복문에서 씁니다: `for x in reversed(a):`.

## 리스트 순회

```
items = ["커피", "지하철", "영화"]
for item in items:
    print(item)

for i, item in enumerate(items, start=1):
    print(i, item)          # 1 커피, 2 지하철, 3 영화

print("영화" in items)      # True — 포함 여부 확인
```

순회 중인 리스트에서 원소를 지우면 일부가 건너뛰어집니다. 리스트 컴프리헨션으로 새 리스트를 만들거나, 복사본 `a[:]`를 순회하세요.

## 리스트 컴프리헨션

리스트 컴프리헨션은 한 줄로 새 리스트를 만듭니다. 표현식, 반복문, 그리고 선택적인 조건으로 구성됩니다.

```
squares = [n * n for n in range(6)]          # [0, 1, 4, 9, 16, 25]
big = [a for a in [250, 1200, 99] if a > 200]  # [250, 1200]
names = [s.strip() for s in [" 안나 ", "올레"]]  # ['안나', '올레']
```

컴프리헨션은 보통 `append`를 쓰는 반복문보다 빠르고 읽기 쉽습니다. 다만 로직이 한 줄로 이해하기 어렵다면, 평범한 반복문이 더 낫습니다.

## 리스트 합치기, 더하기, 빼기

```
a = [1, 2, 3]
b = [3, 4]
print(a + b)       # [1, 2, 3, 3, 4] — 새 리스트
a += b             # a.extend(b)와 같습니다
print([*a, *b])    # 언패킹으로 새 리스트 만들기
```

리스트끼리 `-` 연산자로 뺄 수는 없습니다. 한 리스트에서 다른 리스트의 원소를 제외하려면 컴프리헨션을 쓰세요: `[x for x in a if x not in set(b)]`. 교집합은 집합으로 구하는 것이 편합니다: `set(a) & set(b)`. 다만 이 방법은 순서와 중복이 사라집니다.

## 중첩 리스트와 2차원 리스트

리스트의 리스트는 표나 행렬을 저장하는 간단한 방법입니다.

```
matrix = [[1, 2, 3], [4, 5, 6]]
print(matrix[1][2])     # 6
grid = [[0] * 3 for _ in range(2)]   # 올바른 방법
bad = [[0] * 3] * 2                  # 함정: 같은 리스트를 두 번 참조
bad[0][0] = 9
print(bad)              # [[9, 0, 0], [9, 0, 0]]
```

## 리스트 언패킹

```
first, second, third = [10, 20, 30]
head, *rest = [1, 2, 3, 4]      # head=1, rest=[2, 3, 4]
print(*["a", "b"], sep=", ")    # a, b — 대괄호 없이 출력
```

변수 개수가 리스트 길이와 맞지 않으면 `ValueError`가 납니다. 이때 별표(`*`)가 도움이 됩니다.

## 리스트 복사

`b = a`는 리스트를 복사하지 않고, 같은 객체에 이름을 하나 더 붙일 뿐입니다. 그래서 `b`로 바꾸면 `a`에도 보입니다. 독립된 복사본은 `a.copy()`, `list(a)`, `a[:]`로 명시적으로 만듭니다. 중첩된 데이터에서는 이것으로 부족합니다. 안쪽 리스트는 여전히 공유되므로 `copy.deepcopy(a)`가 필요합니다.

```
import copy
a = [[1, 2], [3]]
b = a.copy()
b[0].append(99)
print(a)                 # [[1, 2, 99], [3]] — 안쪽 리스트는 공유됩니다
c = copy.deepcopy(a)     # 완전히 독립된 복사본
```

## 튜플: 변경할 수 없는 리스트

튜플(`tuple`)은 리스트와 비슷하지만 만든 뒤에는 바꿀 수 없습니다. 고정된 필드를 가진 하나의 기록이지, 계속 늘어나는 목록이 아니라는 신호를 읽는 사람에게 줍니다. 튜플은 간편하게 언패킹되며, 함수가 여러 값을 반환할 때 흔히 사용합니다.

```
expense = (250, "커피")
amount, item = expense
expense[0] = 300
# TypeError: 'tuple' object does not support item assignment
```

변경할 수 없는 값으로만 이루어진 튜플은 해시 가능하므로 딕셔너리의 키로 쓸 수 있습니다. 원소가 하나인 튜플은 쉼표를 붙여 씁니다: `(5,)`.

## 집합: 중복 없는 값

집합(`set`)은 고유한 값만 저장하며 순서를 기억하지 않습니다. 중복을 없애거나 '이 값이 있는가'를 확인하는 가장 빠른 방법이고, 교집합, 합집합, 차집합도 지원합니다.

```
jan = {"식비", "택시", "영화"}
feb = {"식비", "구독"}
print(jan & feb)    # {'식비'}
print(feb - jan)    # {'구독'}
unique = list(dict.fromkeys([3, 1, 3, 2]))   # [3, 1, 2] — 중복 제거, 순서 유지
empty = set()       # {} 는 빈 딕셔너리입니다!
```

## 어떤 컬렉션을 고를까

| 용도 | 컬렉션 |
| --- | --- |

| 순서가 있고 내용을 바꿔야 함 | `list` |

| 고정된 기록 | `tuple` |

| 키로 찾기 | `dict` |

| 중복 없음, '포함 여부' 확인 | `set` |

| 변경할 수 없는 설정 | `frozendict` (Python 3.15) |

`x in list`는 원소를 하나씩 비교하지만, `x in set`은 거의 즉시 끝납니다. 반복문 안에서 큰 리스트에 포함 여부를 여러 번 확인해야 한다면 집합으로 바꾸세요.

## 정리

파이썬 리스트는 순서가 있고 변경할 수 있는 컬렉션입니다. `append`와 `extend`로 추가하고, `pop`과 `remove`로 삭제하고, `a[start:stop:step]` 슬라이스로 일부를 가져옵니다. `sort`는 제자리에서 정렬하고 `None`을 반환하며, `sorted`는 새 리스트를 반환합니다. 복사는 명시적으로 하고, 고정된 기록에는 튜플을, 중복 없는 값에는 집합을 쓰세요. 리스트, 튜플, 딕셔너리, 집합은 '파이썬 3.15: 초보부터 전문가까지' 과정에서 실습으로 다룹니다.

## FAQ

**파이썬의 리스트는 다른 언어의 배열과 어떻게 다른가요?**

파이썬에는 다른 언어와 같은 의미의 기본 배열이 없고, 그 역할을 리스트가 합니다. 리스트에는 서로 다른 타입의 값을 넣을 수 있습니다. 숫자 배열이 필요하면 array 모듈이나 NumPy를 씁니다.

**리스트에서 원소의 인덱스는 어떻게 찾나요?**

a.index(x)는 처음 나오는 위치를 반환하고, 원소가 없으면 ValueError를 냅니다. 호출하기 전에 x in a로 확인하세요.

**순서를 유지하면서 리스트의 중복을 없애려면?**

list(dict.fromkeys(a))를 쓰세요. 딕셔너리는 키를 중복 없이 삽입 순서대로 저장합니다. list(set(a))도 중복은 없애지만 순서는 유지하지 않습니다.

**문자열 리스트를 한 문자열로 합치려면?**

문자열의 join 메서드를 씁니다. ", ".join(["a", "b", "c"])는 "a, b, c"를 만듭니다. 모든 원소가 문자열이어야 하므로, 숫자는 map(str, a)로 먼저 변환하세요.

**리스트 하나에 서로 다른 타입의 값을 넣어도 되나요?**

네. 숫자, 문자열, 다른 리스트, 어떤 객체든 한 리스트에 함께 넣을 수 있습니다. 다만 key 없이 이런 리스트를 정렬하면 숫자와 문자열을 비교하게 되어 TypeError가 납니다.


---
Source: Skillaria.Top (https://skillaria.top)
