리스트 (Lists)

2025. 3. 25. 06:41Programming Languages/Python

리스트 (Lists)

리스트는 파이썬에서 가장 많이 사용되는 자료구조로, 여러 항목을 순서대로 저장할 수 있습니다. 대괄호 [] 안에 쉼표로 구분된 항목들을 나열하여 만듭니다.

리스트 생성하기

# 빈 리스트 생성
empty_list = []
empty_list2 = list()

# 값이 있는 리스트 생성
numbers = [1, 2, 3, 4, 5]
fruits = ["사과", "바나나", "체리"]
mixed = [1, "Hello", 3.14, True]  # 다양한 데이터 타입 포함 가능

리스트 인덱싱과 슬라이싱

리스트의 각 항목은 인덱스(위치)를 통해 접근할 수 있습니다. 인덱스는 0부터 시작합니다.

fruits = ["사과", "바나나", "체리", "딸기", "오렌지"]

# 인덱싱 (특정 위치의 항목 접근)
print(fruits[0])  # 첫 번째 항목: 사과
print(fruits[2])  # 세 번째 항목: 체리

# 음수 인덱스 (뒤에서부터 접근)
print(fruits[-1])  # 마지막 항목: 오렌지
print(fruits[-2])  # 뒤에서 두 번째 항목: 딸기

# 슬라이싱 (범위 추출)
print(fruits[1:4])    # 인덱스 1부터 3까지: ['바나나', '체리', '딸기']
print(fruits[:3])     # 처음부터 인덱스 2까지: ['사과', '바나나', '체리']
print(fruits[2:])     # 인덱스 2부터 끝까지: ['체리', '딸기', '오렌지']
print(fruits[-3:])    # 뒤에서 세 번째부터 끝까지: ['체리', '딸기', '오렌지']

# 스텝 사용하기
print(fruits[::2])    # 처음부터 끝까지 2 간격으로: ['사과', '체리', '오렌지']
print(fruits[::-1])   # 거꾸로 출력: ['오렌지', '딸기', '체리', '바나나', '사과']

리스트 수정하기

리스트는 변경 가능(mutable)한 자료구조로, 생성 후에도 내용을 수정할 수 있습니다.

fruits = ["사과", "바나나", "체리"]

# 특정 항목 변경
fruits[1] = "블루베리"
print(fruits)  # ['사과', '블루베리', '체리']

# 슬라이싱으로 여러 항목 변경
fruits[0:2] = ["딸기", "키위"]
print(fruits)  # ['딸기', '키위', '체리']

# 항목 추가하기
fruits.append("망고")
print(fruits)  # ['딸기', '키위', '체리', '망고']

# 특정 위치에 항목 삽입하기
fruits.insert(1, "오렌지")
print(fruits)  # ['딸기', '오렌지', '키위', '체리', '망고']

# 항목 제거하기
fruits.remove("키위")  # 값으로 제거
print(fruits)  # ['딸기', '오렌지', '체리', '망고']

# 특정 위치의 항목 제거
popped = fruits.pop(1)  # 인덱스로 제거하고 반환
print(popped)  # 오렌지
print(fruits)  # ['딸기', '체리', '망고']

# 마지막 항목 제거
last = fruits.pop()
print(last)    # 망고
print(fruits)  # ['딸기', '체리']

# 리스트 비우기
fruits.clear()
print(fruits)  # []

리스트 메서드

파이썬 리스트는 다양한 내장 메서드를 제공하며, 이를 통해 리스트를 효율적으로 관리할 수 있습니다.

리스트 결합 및 확장

# 리스트 결합하기 (concatenation)
list1 = [1, 2, 3]
list2 = [4, 5, 6]
combined = list1 + list2
print(combined)  # [1, 2, 3, 4, 5, 6]

# extend() 메서드로 리스트 확장하기
fruits = ["사과", "바나나"]
more_fruits = ["체리", "딸기"]
fruits.extend(more_fruits)
print(fruits)  # ['사과', '바나나', '체리', '딸기']

# append와 extend의 차이점
list1 = [1, 2, 3]
list2 = [4, 5]
list1.append(list2)  # 리스트 자체를 항목으로 추가
print(list1)  # [1, 2, 3, [4, 5]]

list3 = [1, 2, 3]
list4 = [4, 5]
list3.extend(list4)  # 리스트의 각 항목을 개별적으로 추가
print(list3)  # [1, 2, 3, 4, 5]

리스트 항목 개수 및 존재 여부 확인

fruits = ["사과", "바나나", "체리", "사과", "오렌지"]

# 특정 항목의 개수 세기
apple_count = fruits.count("사과")
print(f"사과의 개수: {apple_count}")  # 사과의 개수: 2

# 특정 항목의 첫 번째 인덱스 찾기
banana_index = fruits.index("바나나")
print(f"바나나의 인덱스: {banana_index}")  # 바나나의 인덱스: 1

# 항목 존재 여부 확인
has_cherry = "체리" in fruits
print(f"체리가 있나요? {has_cherry}")  # 체리가 있나요? True

has_grape = "포도" in fruits
print(f"포도가 있나요? {has_grape}")  # 포도가 있나요? False

리스트 정렬 및 역순 배치

numbers = [5, 2, 8, 1, 9, 3]
fruits = ["사과", "오렌지", "바나나", "체리"]

# 리스트 정렬하기
numbers.sort()  # 오름차순 정렬 (원본 변경)
print(numbers)  # [1, 2, 3, 5, 8, 9]

fruits.sort()  # 문자열은 알파벳 순 정렬
print(fruits)  # ['바나나', '사과', '오렌지', '체리'] (한글은 가나다 순)

# 내림차순 정렬
numbers.sort(reverse=True)
print(numbers)  # [9, 8, 5, 3, 2, 1]

# 원본 변경 없이 정렬된 새 리스트 얻기
numbers = [5, 2, 8, 1, 9, 3]
sorted_numbers = sorted(numbers)
print(numbers)        # [5, 2, 8, 1, 9, 3] (원본 유지)
print(sorted_numbers) # [1, 2, 3, 5, 8, 9]

# 리스트 역순으로 뒤집기
fruits = ["사과", "바나나", "체리", "딸기"]
fruits.reverse()  # 원본 변경
print(fruits)  # ['딸기', '체리', '바나나', '사과']

리스트 복사하기

# 주의: 단순 할당은 참조만 복사됩니다
original = [1, 2, 3]
not_copy = original  # 참조 복사 (같은 리스트를 가리킴)
not_copy[0] = 99
print(original)  # [99, 2, 3] (원본도 변경됨)

# 리스트 복사 방법 1: copy() 메서드
original = [1, 2, 3]
copy1 = original.copy()
copy1[0] = 99
print(original)  # [1, 2, 3] (원본 유지)
print(copy1)     # [99, 2, 3]

# 리스트 복사 방법 2: list() 생성자
original = [1, 2, 3]
copy2 = list(original)
copy2[0] = 99
print(original)  # [1, 2, 3]
print(copy2)     # [99, 2, 3]

# 리스트 복사 방법 3: 슬라이싱
original = [1, 2, 3]
copy3 = original[:]
copy3[0] = 99
print(original)  # [1, 2, 3]
print(copy3)     # [99, 2, 3]

주의: 얕은 복사(Shallow Copy)와 깊은 복사(Deep Copy)

리스트 안에 리스트가 있는 경우, 단순 복사는 내부 리스트의 참조를 복사합니다.

import copy

# 중첩 리스트
original = [1, 2, [3, 4]]

# 얕은 복사
shallow_copy = original.copy()
shallow_copy[2][0] = 99
print(original)      # [1, 2, [99, 4]] (내부 리스트 변경됨)
print(shallow_copy)  # [1, 2, [99, 4]]

# 깊은 복사 (내부 객체까지 모두 복사)
original = [1, 2, [3, 4]]
deep_copy = copy.deepcopy(original)
deep_copy[2][0] = 99
print(original)   # [1, 2, [3, 4]] (원본 유지)
print(deep_copy)  # [1, 2, [99, 4]]

리스트 컴프리헨션(List Comprehension)

리스트 컴프리헨션은 간결하게 리스트를 생성하는 파이썬의 강력한 기능입니다.

# 기본 문법: [표현식 for 항목 in 시퀀스]

# 1부터 10까지의 제곱 리스트 생성
squares = [x**2 for x in range(1, 11)]
print(squares)  # [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

# 조건이 있는 리스트 컴프리헨션
even_squares = [x**2 for x in range(1, 11) if x % 2 == 0]
print(even_squares)  # [4, 16, 36, 64, 100]

# 중첩 루프를 사용한 리스트 컴프리헨션
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flattened = [num for row in matrix for num in row]
print(flattened)  # [1, 2, 3, 4, 5, 6, 7, 8, 9]

# 복잡한 변환
names = ["apple", "banana", "cherry"]
lengths = [len(name) for name in names]
print(lengths)  # [5, 6, 6]

# if-else를 사용한 조건부 표현식
numbers = [1, 2, 3, 4, 5]
result = ["짝수" if n % 2 == 0 else "홀수" for n in numbers]
print(result)  # ['홀수', '짝수', '홀수', '짝수', '홀수']

리스트 컴프리헨션은 일반 반복문보다 코드를 간결하게 만들고, 때로는 성능도 더 좋습니다. 하지만 너무 복잡한 로직을 넣으면 가독성이 떨어지므로 적절하게 사용하는 것이 좋습니다.

다차원 리스트

리스트 안에 리스트를 포함하여 다차원 구조를 만들 수 있습니다.

# 2차원 리스트 (행렬)
matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]

# 행과 열 접근하기
print(matrix[1])     # 두 번째 행 전체: [4, 5, 6]
print(matrix[1][2])  # 두 번째 행, 세 번째 열: 6

# 행 순회하기
for row in matrix:
    print(row)

# 모든 요소 순회하기
for row in matrix:
    for element in row:
        print(element, end=" ")
    print()

# 특정 행 또는 열 변경하기
matrix[0] = [10, 11, 12]  # 첫 번째 행 변경
print(matrix)

# 3차원 리스트 예제 (큐브)
cube = [
    [[1, 2], [3, 4]],
    [[5, 6], [7, 8]]
]
print(cube[1][0][1])  # 6 (두 번째 층, 첫 번째 행, 두 번째 열)

'Programming Languages > Python' 카테고리의 다른 글

튜플 (Tuples)  (0) 2025.03.25
파이썬의 얕은 복사(Shallow Copy)와 깊은 복사(Deep Copy)  (1) 2025.03.25
중첩 반복문 (Nested Loops)  (0) 2025.03.25
반복문 제어 및 활용  (0) 2025.03.21
반복문 (Loops)  (0) 2025.03.21