리스트(List) 슬라이싱과 인덱싱 심화: 데이터 접근의 마법사
1. 서론: 리스트 데이터, 원하는 부분만 쏙쏙 뽑아내기
이전 챕터에서 우리는 파이썬 리스트의 기본적인 개념과 생성 방법, 그리고 append(), remove()와 같은 메서드를 사용하여 리스트의 요소를 추가, 삭제, 수정하는 방법을 배웠습니다. 리스트는 순서가 있는 데이터의 집합이므로, 특정 위치의 요소에 접근하거나 리스트의 특정 부분만을 잘라내어 새로운 리스트를 만드는 기능은 매우 중요합니다. 이때 사용되는 핵심적인 기법이 바로 ‘인덱싱(Indexing)’과 ‘슬라이싱(Slicing)’입니다. 우리는 이미 문자열 챕터에서 이 개념들을 간략하게 다루었지만, 리스트에서는 더욱 다양한 방식으로 활용될 수 있습니다. 이 챕터에서는 파이썬 리스트의 인덱싱과 슬라이싱 기법을 더 깊이 있게 탐구하고, 이를 통해 리스트 데이터를 더욱 정교하고 효율적으로 다루는 고급 활용법에 대해 알아보겠습니다. 인덱싱과 슬라이싱을 마스터하는 것은 여러분의 파이썬 데이터 처리 능력을 한 단계 더 끌어올릴 것입니다.
2. 리스트 인덱싱 심화: 요소에 정확히 접근하기
리스트의 각 요소는 고유한 위치 번호, 즉 ‘인덱스(Index)’를 가집니다. 인덱스를 사용하여 리스트의 특정 요소에 접근할 수 있습니다.
2.1. 양수 인덱싱 (0부터 시작)
가장 왼쪽의 요소부터 0으로 시작하여 1씩 증가하는 인덱스를 사용합니다.
my_list = [10, 20, 30, 40, 50]
print(my_list[0]) # 출력: 10 (첫 번째 요소)
print(my_list[2]) # 출력: 30 (세 번째 요소)
print(my_list[4]) # 출력: 50 (마지막 요소)
# 존재하지 않는 인덱스에 접근하면 IndexError 발생
# print(my_list[5]) # IndexError: list index out of range
2.2. 음수 인덱싱 (-1부터 시작)
가장 오른쪽의 요소부터 -1로 시작하여 1씩 감소하는 인덱스를 사용합니다. 리스트의 마지막 요소에 접근할 때 매우 유용합니다.
my_list = [10, 20, 30, 40, 50]
print(my_list[-1]) # 출력: 50 (마지막 요소)
print(my_list[-3]) # 출력: 30 (뒤에서 세 번째 요소)
print(my_list[-5]) # 출력: 10 (첫 번째 요소)
2.3. 중첩 리스트(Nested List) 인덱싱
리스트 안에 또 다른 리스트가 포함된 중첩 리스트의 요소에 접근하려면 여러 개의 인덱스를 사용합니다. 각 인덱스는 해당 레벨의 리스트에 대한 접근을 의미합니다.
matrix = [
[1, 2, 3], # matrix[0]
[4, 5, 6], # matrix[1]
[7, 8, 9] # matrix[2]
]
print(matrix[0]) # 출력: [1, 2, 3] (첫 번째 행 전체)
print(matrix[1][1]) # 출력: 5 (두 번째 행의 두 번째 요소)
print(matrix[2][-1]) # 출력: 9 (세 번째 행의 마지막 요소)
# 3차원 리스트 예시
cube = [
[["a", "b"], ["c", "d"]],
[["e", "f"], ["g", "h"]]
]
print(cube[0][1][0]) # 출력: c (첫 번째 층, 두 번째 행, 첫 번째 요소)
3. 리스트 슬라이싱 심화: 부분 리스트 추출하기
슬라이싱은 리스트의 특정 범위(부분)를 잘라내어 새로운 리스트를 만드는 기법입니다. 원본 리스트는 변경되지 않습니다. [시작_인덱스:끝_인덱스:단계] 형식을 사용합니다.
my_list = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
3.1. 기본 슬라이싱: [시작_인덱스:끝_인덱스]
시작_인덱스부터끝_인덱스 - 1까지의 요소를 포함합니다.끝_인덱스는 포함되지 않습니다.
print(my_list[2:5]) # 출력: [2, 3, 4] (인덱스 2부터 4까지)
print(my_list[0:3]) # 출력: [0, 1, 2]
3.2. 시작 인덱스 또는 끝 인덱스 생략
시작_인덱스를 생략하면 리스트의 처음부터 시작합니다.끝_인덱스를 생략하면 리스트의 끝까지 포함합니다.
print(my_list[:5]) # 출력: [0, 1, 2, 3, 4] (처음부터 인덱스 4까지)
print(my_list[5:]) # 출력: [5, 6, 7, 8, 9] (인덱스 5부터 끝까지)
print(my_list[:]) # 출력: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] (리스트 전체 복사)
3.3. 음수 인덱스를 이용한 슬라이싱
음수 인덱스도 슬라이싱에 사용할 수 있습니다.
print(my_list[-5:-2]) # 출력: [5, 6, 7] (뒤에서 5번째부터 뒤에서 3번째까지)
print(my_list[-3:]) # 출력: [7, 8, 9] (뒤에서 3번째부터 끝까지)
print(my_list[:-5]) # 출력: [0, 1, 2, 3, 4] (처음부터 뒤에서 6번째까지)
3.4. 단계(Step)를 이용한 슬라이싱: [시작_인덱스:끝_인덱스:단계]
단계는 몇 칸씩 건너뛰면서 요소를 가져올지 지정합니다. 기본값은 1입니다.
print(my_list[::2]) # 출력: [0, 2, 4, 6, 8] (처음부터 끝까지 2칸씩 건너뛰기)
print(my_list[1::2]) # 출력: [1, 3, 5, 7, 9] (인덱스 1부터 끝까지 2칸씩 건너뛰기)
# 음수 단계를 사용하면 리스트를 뒤집을 수 있습니다.
reversed_list = my_list[::-1]
print(reversed_list) # 출력: [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
# 특정 범위만 뒤집기
print(my_list[5:1:-1]) # 출력: [5, 4, 3, 2] (인덱스 5부터 인덱스 2까지 역순)
4. 슬라이싱을 이용한 리스트 수정 및 삭제
슬라이싱은 단순히 부분 리스트를 추출하는 것을 넘어, 리스트의 특정 부분을 수정하거나 삭제하는 데도 활용될 수 있습니다. 이는 리스트가 변경 가능한(Mutable) 자료형이기 때문에 가능합니다.
4.1. 슬라이싱을 이용한 요소 수정/교체
슬라이싱으로 선택된 범위에 새로운 리스트를 할당하여 요소를 수정하거나 교체할 수 있습니다. 이때 할당하는 리스트의 요소 개수가 슬라이싱 범위의 요소 개수와 달라도 상관없습니다.
numbers = [10, 20, 30, 40, 50]
print(f"원본 리스트: {numbers}") # 출력: 원본 리스트: [10, 20, 30, 40, 50]
numbers[1:3] = [25, 35] # 인덱스 1부터 2까지의 요소를 [25, 35]로 교체
print(f"슬라이싱 수정 후: {numbers}") # 출력: 슬라이싱 수정 후: [10, 25, 35, 40, 50]
numbers[1:4] = ["a", "b", "c", "d"] # 교체되는 요소의 개수가 달라도 됩니다.
print(f"슬라이싱 교체 후: {numbers}") # 출력: 슬라이싱 교체 후: [10, 'a', 'b', 'c', 'd', 50]
4.2. 슬라이싱을 이용한 요소 삭제
슬라이싱으로 선택된 범위에 빈 리스트 []를 할당하면 해당 범위의 요소들을 삭제할 수 있습니다.
my_list = [1, 2, 3, 4, 5]
print(f"원본 리스트: {my_list}") # 출력: 원본 리스트: [1, 2, 3, 4, 5]
my_list[1:4] = [] # 인덱스 1부터 3까지의 요소 (2, 3, 4) 삭제
print(f"슬라이싱 삭제 후: {my_list}") # 출력: 슬라이싱 삭제 후: [1, 5]
5. 인덱싱과 슬라이싱의 활용 팁
- 리스트 복사:
my_list[:]는 리스트의 모든 요소를 복사하여 새로운 리스트를 만듭니다. 이는 얕은 복사(shallow copy)입니다.
python
original = [1, 2, 3]
copied = original[:]
print(copied) # 출력: [1, 2, 3]
print(original is copied) # 출력: False (다른 객체) - 리스트 뒤집기:
my_list[::-1]는 리스트를 뒤집은 새로운 리스트를 반환합니다. - 짝수/홀수 인덱스 요소 추출:
my_list[::2](짝수 인덱스),my_list[1::2](홀수 인덱스)
6. 결론: 리스트 데이터의 정교한 제어
이 챕터를 통해 여러분은 파이썬 리스트의 인덱싱과 슬라이싱 기법을 더 깊이 있게 학습했습니다. 양수/음수 인덱스를 사용하여 리스트의 특정 요소에 접근하는 방법, 중첩 리스트의 요소에 접근하는 방법, 그리고 [시작:끝:단계] 형식을 사용하여 리스트의 특정 부분을 잘라내거나 뒤집는 슬라이싱 기법을 마스터했습니다. 또한, 슬라이싱을 이용하여 리스트의 요소를 수정하거나 삭제하는 강력한 기능까지 살펴보았습니다.
인덱싱과 슬라이싱은 파이썬에서 리스트(및 문자열, 튜플)와 같은 시퀀스 자료형의 데이터를 정교하게 제어하는 데 필수적인 도구입니다. 데이터 분석에서 특정 범위의 데이터를 추출하거나, 웹 크롤링에서 필요한 정보만을 파싱하거나, 게임 개발에서 특정 위치의 객체를 조작하는 등 다양한 실제 프로그래밍 상황에서 이 기술들은 빛을 발할 것입니다.
이제 여러분은 파이썬의 핵심 자료 구조인 리스트를 생성하고, 조작하며, 원하는 부분만을 효율적으로 추출할 수 있는 능력을 갖추게 되었습니다. 다음 챕터에서는 파이썬의 또 다른 중요한 시퀀스 자료형인 ‘튜플(Tuple)’에 대해 알아보겠습니다. 튜플은 리스트와 유사하지만 ‘불변(Immutable)’하다는 중요한 차이점을 가집니다. 오늘 배운 인덱싱과 슬라이싱을 활용하여 다양한 리스트 데이터를 직접 다루어 보면서, 여러분의 파이썬 실력을 더욱 단단하게 다지세요!
