오늘은 리스트에 대하여 알아보겠습니다. 내용이 좀 많네요.
목차를 이용해서 원하는 정보를 얻어가시길... ㅎㅎ

컬렉션 안에 리스트 타입이 있는데요
컬렉션은 간단하게 말하면
1개 이상 데이터를 관리합니다.
| 타입명 | 기호(리터럴) | 특징 | 생성법 |
| *리스트 | [] | - 순서 O - 값중복 O |
list(), [] |
| *딕셔너리 | {} | - 순서 X(3.7이후 순서유지) - 키와 값으로 매핑 - 키는 고유하다 |
dict(), {} |
| 튜플 | () | - 순서 O - 수정 X, 단순히 값을 묶는다 |
tuple(), (,) |
| 집합 | {} | - 중복제거 | set() |
리스트는 마치 여러 칸이 있는 서랍장처럼 다양한 데이터를 순서대로 담을 수 있는 마법의 그릇입니다. 특히 파이썬의 리스트는 다른 프로그래밍 언어의 배열(Array)과 달리 서로 다른 타입의 데이터(정수, 실수, 문자열 등)를 하나의 리스트에 모두 담을 수 있다는 엄청난 유연성을 자랑합니다.
1. 리스트 생성하기 (list() vs [])
리스트를 만드는 방법은 크게 두 가지 뉘앙스로 나뉩니다.
1) list() 함수 사용
처음에는 빈 깡통(빈 리스트)을 만들어 두고, 나중에 로직에 따라 데이터를 하나씩 추가할 때 주로 사용합니다.
# 1. 빈 리스트 생성
datas = list()
print(type(datas)) # <class 'list'>
# 2. 데이터 추가 (서로 다른 타입 혼용 가능!)
datas.append(1) # 정수
datas.append(3.14) # 실수
datas.append('hello') # 문자열
print(datas) # [1, 3.14, 'hello']
💡 추가 지식 (데이터 분석 관점) 파이썬 기본 리스트는 이렇게 타입이 섞여도 상관없지만, 향후 데이터 분석에서 배우게 될 NumPy 배열(ndarray), Pandas 시리즈(Series), 파이토치 텐서(Tensor) 등은 연산 속도와 효율성을 위해 반드시 단일 타입으로만 구성되어야 한다는 차이점이 있습니다.
2) 대괄호 [] 사용
리스트를 생성함과 동시에 초기 데이터를 세팅할 때 직관적으로 사용합니다. 반복문과 결합하는 '리스트 컴프리헨션(List Comprehension)' 문법에서도 이 대괄호를 사용합니다.
# 생성과 동시에 데이터 세팅
datas = [1, 3.14, 'hello']
datas.append(2)
datas.append('hi')
print(datas) # [1, 3.14, 'hello', 2, 'hi']
2. 리스트에 데이터 추가 및 병합
1) 기본 추가: append()
데이터를 리스트의 맨 뒤(마지막)에 하나씩 밀어 넣습니다.
datas.append(100)
print(datas) # [1, 3.14, 'hello', 2, 'hi', 100]
2) 리스트 간 더하기 (+ 연산자)
두 개의 리스트를 합쳐서 새로운(독립된) 리스트를 만들어 냅니다. 원본 리스트들은 변하지 않습니다.
dummy = ['hello',1,2]
new_list = datas + dummy # 두 리스트가 병합된 새로운 리스트 생성
print(new_list) # [1, 3.14, 'hello', 2, 'hi', 100, 'hello', 1, 2]
3. 리스트 인덱싱과 2차원 리스트 (차원 축소)
리스트에서 특정 위치의 데이터를 콕 집어 추출하는 행위를 인덱싱(Indexing)이라고 합니다. 문자열 인덱싱과 동일하게 0부터 시작합니다.
- 차원 축소의 원리: 1차원 리스트에서 인덱싱을 하면 0차원(스칼라, 단일 값) 데이터가 추출됩니다.
datas = [10, 20, 30]
print(datas[0]) # 10 (리스트가 아닌 단일 정수값 추출)
⚠️ 인덱싱 주의사항: IndexError
리스트가 가진 멤버 수를 초과하는 인덱스 번호를 부르면 에러가 발생하며 프로그램이 멈춥니다.
datas[100] -> IndexError: list index out of range
2차원 리스트 (행렬 구조)
리스트 안에 또 다른 리스트를 넣을 수 있습니다. 여기서 값을 뽑아낼 때는 인덱싱을 두 번 연속으로 사용합니다.
arrs = [
[1, 2, 3, 4], # 0번 인덱스
[5, 6, 7, 8], # 1번 인덱스
[9, 10, 11, 12] # 2번 인덱스
]
# 요구사항: 숫자 '7'을 추출하시오.
# 1단계: arrs[1]을 통해 두 번째 행([5, 6, 7, 8]) 추출 (2차원 -> 1차원 축소)
# 2단계: 그 안에서 인덱스 2번 추출 (1차원 -> 스칼라 값)
print(arrs[1][2]) # 출력: 7
4. 슬라이싱 (차원 유지)
특정 구간을 잘라내는 슬라이싱은 인덱싱과 달리 원본의 차원을 그대로 유지합니다.
2차원 리스트를 슬라이싱 하면 2차원 리스트가, 1차원 리스트를 슬라이싱 하면 1차원 리스트가 반환됩니다.
# 원본 카피 (얕은 복사)
copy_arrs = arrs[:]
# 인덱스 1부터 맨 마지막 앞까지 잘라내기 (차원 유지)
print(arrs[1:-1]) # 출력: [[5, 6, 7, 8]]
5. 값 수정, 삭제, 추출의 모든 것
1) 값 수정하기: [index]
인덱싱으로 위치를 지정하고 새로운 값을 할당(대입)하면 원본이 바로 수정됩니다.
arrs[-1] = 10 # 맨 마지막 요소를 10으로 변경
2) 특정 멤버 삭제 : del
파이썬의 내장 키워드인 del을 사용하면 해당 메모리 위치의 데이터를 완전히 지워버립니다.
del arrs[-1] # 맨 마지막 멤버 삭제
3) 리스트 전체 비우기: clear()
리스트 객체(그릇) 자체는 살려두고, 안에 있는 내용물만 싹 비우고 싶을 때 사용합니다.
arrs.clear() # 결과: []
4) 값 추출 후 제거: pop()
pop()은 단순히 삭제만 하는 것이 아니라, 맨 마지막에 있는 데이터를 리스트에서 꺼내어(반환) 보여준 뒤 삭제합니다.
(마치 책상 위에 책을 쌓아두고 맨 위에서부터 가져가는 Stack 구조와 같습니다.)
arrs = [1, 2, 3]
last_item = arrs.pop()
print(last_item) # 3 출력
print(arrs) # [1, 2] 남음
6. append() vs extend()의 치명적 차이
이 두 가지는 초보자분들이 가장 많이 헷갈리는 부분이라고 합니다.
리스트 안에 다른 리스트를 넣을 때 작동 방식이 완전히 다릅니다.
- append(리스트): 리스트 덩어리 자체를 하나의 멤버로 취급하여 하위 레벨로 집어넣습니다.
- extend(리스트): 리스트의 껍데기를 깨고, 안에 있는 멤버들을 꺼내어 같은 레벨로 펼쳐서 연장시킵니다. (+ 연산자와 비슷하지만, extend는 원본 리스트 자체를 변화시킨다는 차이가 있습니다.)
arrs = [10, 20]
# 1. append 적용 (리스트 속의 리스트)
arrs.append([100, 101])
print(arrs) # [10, 20, [100, 101]]
arrs = [10, 20] # 다시 초기화
# 2. extend 적용 (동등한 레벨로 확장)
arrs.extend([100, 101])
print(arrs) # [10, 20, 100, 101]
7. 리스트 정렬: sort()
리스트 안의 데이터를 오름차순이나 내림차순으로 정렬할 때 사용합니다.
arrs = [3, 1, 4, 2]
# 오름차순 (기본)
arrs.sort()
print(arrs) # [1, 2, 3, 4]
# 내림차순 정렬
arrs.sort(reverse=True)
print(arrs) # [4, 3, 2, 1]
💡 추가 지식: sort() vs sorted()
- 리스트.sort(): 원본 리스트 자체의 순서를 뒤집어 버립니다. (리턴 값이 None입니다.)
- sorted(리스트): 파이썬 내장 함수로, 원본은 그대로 둔 채 정렬된 '새로운 리스트'를 만들어서 반환합니다. 원본 데이터를 보존해야 할 때는 반드시 sorted()를 사용해야 합니다!
오늘의 한 마디
통제가능한 영역과 통제 불가능한 영역을 잘 구분해서 인생을 살아가야한다. 내가 통제할 수 있는 것들에만 집중하면서 살아가야 마음도 편하다. 물론 우리는 통제 불가능한 영역에 대한 생각할 때 불안과 걱정이 생기는데 인간이라면 이런 생각을 안할 수 없다고 생각한다.
하지만! 통제 불가능한 영역은 3분 이내의 생각을 하고 내가 할 수 있는 것을 메모장에 적으면서 에너지를 얻어야하지 않나 싶다.
내가 통제할 수 있는 것을 열심히 해보자.