학습 자료 : https://docs.python.org/ko/3.13/tutorial/datastructures.html
자료구조
리스트
파이썬의 리스트는 객체지향적으로 설계되어 있어 다양한 내장 메서드를 제공한다. 아래 메서드들은 대부분 리스트를 제자리에서(in-place) 수정하고 None 을 반환한다.
요소 추가 및 확장
list.append(x): 리스트 끝에 하나의 요소를 추가한다.list.extend(iterable): 리스트 끝에 다른 iterable(리스트, 튜플 등)의 모든 요소를 추가한다.
요소 삽입 및 삭제
list.insert(i, x): 특정 인덱스 i에 요소를 삽입한다.list.remove(x): 리스트에서 첫 번째로 발견된 x의 값을 삭제한다.list.pop([i]): 특정 인덱스의 i의 요소를 삭제하고 그 요소를 반환한다. 인덱스를 생략하면 마지막 요소를 삭제하고 반환한다.
리스트 정보 조회
list.index(x[, start[, end]]): 리스트에서 x가 처음 나타나는 인덱스를 반환한다. start와 end로 탐색 범위를 지정할 수 있다.list.count(x): 리스트에 x가 몇번 등장하는지 횟수를 반복함
리스트 정렬 및 뒤집기
list.sort(*, key=None, reverse=False): 리스트를 제자리에서 정렬한다. reverse=True 로 내림차순 정렬이 가능하다.
리스트 복사
list.copy(): 리스트의 얕은 복사본을 반환한다.
- 반환값
None:append(),sort(),reverse()와 같이 리스트를 직접 수정하는 대부분의 메서드는 별도의 값을 반환하지 않고None을 반환한다. 이는 제자리에서 수정하는 메서드라는 것을 나타내느 파이썬의 설계 원칙이다. - 비교 가능성: 파이썬은 서로 다른 자료형을 비교할 수 없다. 따라서
[1, 'hello']처럼 정수와 문자열이 섞여 있는 리스트는sort()메서드로 정렬할 수 없다. 이는 자바에서 int와 String 을 직접 비교할 수 없는 것과 같은 개념이다.
리스트를 Stack 으로 사용하기
스택은 마지막에 들어간 것이 가장 먼저 나오는 LIFO 구조를 가지고 있다. 파이썬의 list는 이 스택 기능을 아주 쉽게 구현할 수 있다.
append(): 스택의 맨 위에 항목을 추가한다.pop(): 스택의 맨 위에서 항목을 꺼낸다
Queue 로 리스트 사용하기
큐는 먼저 들어간 것이 먼저 나오는 FIFO 구조이다.
list는 큐로 사용하기에 비효율적이다. 따라서 큐를 구현할 때는 collections 모듈의 deque를 사용해야한다. deaue는 양쪽 끝에ㅓ 데이터를 넣고 빼는데 최적화 되어있어, 큐처럼 사용할 때 훨씬 빠르다append(): 줄의 맨 뒤에 추가(새로운 사람이 줄을 서는 것)popleft(): 줄의 맨 앞에서 꺼낸다
⭐⭐⭐리스트 컴프리핸션(List Comprehensions)
리스트 컴프리헨션은 리스트를 만드는 아주 간결한 방법이다. for 반복문이나 map, filter 함수를 여러줄에 걸쳐 쓰는 대신, 한 줄로 깔끔하게 리스트를 만들 수 있다.
- 기본형식은
[표현식 for 항목 in 이터러블 if 조건]이다. - 리스트 컴프리헨션의 장점
- 코드가 짧고 간결하다
- 읽기 쉽다
- 속도가 빠르다 : 파이썬이 내부적으로 최적화해서 일반적인 for 루프보다 더 빠르게 작동한다.
for문으로 숫자의 제곱 리스트를 만드는 것보다 아래와 같이 한줄로 쓰는 것이 훨씬 간단하다.
squares = [x**2 for x in range(10)]
# 파이썬에서 **는 거듭제곱 연산자이다. 즉 x**2는 x의 2승임
여러 for문을 중첩해서 써야 할 때도 한 줄로 쓸 수 있다.
[(x,y) for x in [1,2,3] for y in [3,1,4] if x !=y]
위 코드는 두 개의 for 문과 하나의 if 문을 사용한 것과 완전히 똑같다.
중첩된 리스트 컴프리헨션
중첩된 컴프리헨션은 바깥쪽 대괄호 안에 [표현식 for ...] 형태의 또 다른 컴프리헨션이 들어가는 구조임
matrix = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
]
[[row [i] for row in matrix] for i in range(4)]
- 위 코드는 세단계로 분해해서 이해할 수 있다.
- 바깥쪽 for 루프 :
for in range(4)는 i를 0,1,2,3 으로 순회하며 네 번 반복함. 이는 전치된 행렬의 각 열을 생성하는 역할을 한다. - 안쪽 리스트 컴프리헨션:
[row[i] for row in matrix]는 바깥 루프의 i 값에 따라 각 행에서 i번째 요소를 가져와 새로운 리스트를 만든다.- i가 0일 때:
[matrix[0][0], matrix[1][0], matrix[2][0]] - i가 1일 때:
[matrix[0][1], matrix[1][1], matrix[2][1]]
- i가 0일 때:
- 결과적으로 바깥쪽 루프가 반복될 때마다 생서오딘 새로운 리스트가 최종 리스트에 추가된다. 이 방법은 for 루프를 세 번 중첩해서 쓰는것보다 훨씬 간결하고 직관적이다.
del 문 : 리스트에서 항목 제거하기
del 문은 리스트에서 인덱스를 이용해 특정 항목을 제거하는 데 사용된다. pop() 메서드는 항목을 제거하고 그 값을 반환하지만, del은 반환값이 없다.
- 항목 제거 :
del a[0]은 a 리스트의 첫번째 항목을 삭제한다. - 슬라이스 제거 :
del a[2:4]는 a 리스트의 2번 인덱스부터 4번 인덱스 이전까지의 항목들을 삭제한다. - 리스트 비우기 :
del a[:]는 리스트의 모든 항목을 삭제하여 빈 리스트로 만든다
튜플과 시퀀스
튜플은 리스트와 유사한 시퀀스형 자료형이지만 결정적이 차이점은 불변이라는 점이다.
- 생성: 튜플은 쉼표로 구분된 값들로 만든다.
- 불변성:
t[0] = 88888처럼 튜플의 요소를 변경할 수 없다. 이는 자바에서 final 키워드로 선언된 객체의 참조를 변경할 수 없는 것과 유사하다. - 용도: 튜플은 보통 이질적인 데이터를 묶을 때 사용한ㄷ다. 함수의 반환값이 여러개일때, 이 값들을 묶어서 반환하는 용도로도 많이 사용한다.
집합(Set)
집합은 중복된 요소를 허용하지 않는 순서가 없는 컬렉션이다. 기본적인 용도는 멤버십 검사와 중복 엔트리 제거이다.
- 생성:
set()함수로 만든다. 빈 집합은 반드시set()으로 만들어야 한다.주요 용도
- 중복 제거: 리스트를
set으로 변환하면 중복된 값이 자동으로 사라짐 - 멤버십 검사: 특정 요소가 집합에 있는지 in 연산자로 확인하는 속도가 매우 빠르다
# 1. 집합 생성
fruits = {'apple', 'orange', 'banana', 'apple', 'pear'}
print(fruits)
# 출력: {'pear', 'orange', 'apple', 'banana'}
# 'apple'이 하나만 남고 순서가 뒤죽박죽인 것을 볼 수 있다.
# 2. 빈 집합 생성
empty_set = set()
print(empty_set)
# 출력: set()
# 리스트를 집합으로 변환하여 중복 제거
numbers = [1, 2, 3, 2, 1, 4]
unique_numbers = set(numbers)
print(unique_numbers)
# 출력: {1, 2, 3, 4}
# 문자열을 집합으로 변환 (각 문자가 요소가 됨)
my_string = "hello"
letters = set(my_string)
print(letters)
# 출력: {'h', 'e', 'l', 'o'}
# 'l'이 하나만 남습니다.
딕셔너리
딕셔너리는 키와 값 쌍으로 이루어진 데이터의 집합이다. 순서가 없는 데이터 구조이고, 인덱스를 숫자가 아닌 키로 접근한다는 점에서 리스트나 튜플과 다르다.
key: 키는 중복될 수 없으며, 불변 자료형만 가능하다. 따라서 리스트는 가변적이므로 키가 될 수 없다.value: 어떤 자료형이든 가능하며, 중복도 혀용된다.
딕셔너리 생성 : {} 중괄호를 사용하여 키: 값 쌍을 나열해 만든다. 빈 딕셔너리는 {}로 생성한다.
# 빈 딕셔너리
empty_dict = {}
# 키-값 쌍을 가진 딕셔너리
tel = {'jack': 4098, 'sape': 4139}
데이터 추가, 접근 및 수정
# 빈 딕셔너리 생성
tel = {}
# 1. 데이터 추가(키가 없을 때)
tel['jack'] = 4098
tel['jack'] = 4139
tel['jack'] = 4127
print("데이터 추가 후:", tel)
# 2.데이터 접근
print("\n'jack'의 전화번호:", tel['jack'])
# 3. 데이터 수정 (키가 이미 있을 때)
# guido 의 전화번호를 4127에서 4128로 변경
tel['guido'] = 4128
print("\n데이터 수정 후:", tel)
# 4. 데이터 삭제
del tel['sape']
print("\n데이터 삭제 후:", tel)
# 5. 존재하지 않는 키에 접근 시도
# 이 코드는 오류를 발생시킵니다. 주석 처리
# print(tel['terry'])
데이터 추가 후: {'jack': 4098, 'sape': 4139, 'guido': 4127}
'jack'의 전화번호: 4098
데이터 수정 후: {'jack': 4098, 'sape': 4139, 'guido': 4128}
데이터 삭제 후: {'jack': 4098, 'guido': 4128}루프 테크닉
파이썬은 루프를 더 효율적이고 읽기 쉽게 만드는 다양한 내장함수를 제공한다.
1. items(): 딕셔너리 루프
딕셔너리에서 키와 값을 동시에 순회할 때 items()메서드를 사용한다.
이 메서드는 튜플 형태의 키,값 쌍을 반환한다.
knithgts = {'gallahad': 'the pure', 'robin': 'the brave'}
for k, v in knights.items():
print(k, v)
# 출력:
# gallahad the pure
# robin the brave
2. enumerate(): 인덱스와 값 동시에 얻기
enumerate() 함수는 리스트나 튜플을 순회할 때 인덱스와 값을 함께 얻을 수 있게 해줌
for i, v in enumerate(['tic', 'tac', 'toe']):
print(i, v)
# 출력:
# 0 tic
# 1 tac
# 2 toe
별도의 카운터 변수를 만들고 1씩 증가시키는 것보다 훨씬 간편하고 직관적이다.
3. reversed() 와 sorted(): 순서 바꾸기
이 두함수는 원본 데이터를 훼손하지 않고 원하는 순서로 데이터를 처리할 수 있어 매우 유용하다.
reversed(): 시퀀스를 역순으로 순회하게 해줌for i in reversed(range(1, 10, 2)): print(i) # 9, 7, 5 , 3, 1 출력sorted(): 시퀀스를 정렬된 상태로 순회하게 해줌. 원본 리스트는 그대로 두고 새로운 정렬된 리스트를 반환함basket = ['apple', 'orange', 'apple'] for i in sorted(basket): print(i) # apple, apple, orange 출력
4. sorted(set()): 고유한 값만 정렬해서 순회하기
set()을 사용해 중복을 제거하고, sorted()로 정렬하여 순회하는 방식은 파이썬에서 자주 사용되는 관용구이다.
basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana']
for f in sorted(set(basket)):
print(f)
# 출력:
# apple
# banana
# orange
# pear'Python' 카테고리의 다른 글
| [Python] 모듈 (0) | 2025.09.25 |
|---|---|
| [Python] 조건문·반복문·함수 (0) | 2025.09.25 |