코딩 여정을 시작할 때 자료구조의 기본 사항을 이해하는 것이 중요합니다. 자료 구조란 데이터 구조 + 연산 을 의미합니다. 이번에는 “배열“에 대해 공부한 내용을 정리해보았습니다.
배열에는 배열의 크기를 미리 정하는지 여부에 따라 정적 배열과 동적 배열로 나뉩니다.
정적 배열 Static Arrays
정적 배열이란?
정적 배열은 각 상자에 고유 번호가 붙은 일련의 상자로 생각하면 됩니다. 각 상자에는 숫자나 단어와 같은 데이터 조각이 포함될 수 있습니다.
정적 배열은 상자 행을 설정한 후에는 상자 수를 변경할 수 없으며 각 상자에는 고정된 위치가 있다고 생각하면 됩니다.
정적 배열의 특성
고정된 크기
정적 배열은 미리 결정된 크기를 가지고 있습니다. 5개의 요소를 저장하기 위해 배열을 생성하면 완전히 고정됩니다.
전체 배열을 다시 정의하지 않고는 6번째 요소를 추가할 수 없습니다.
동질적인 요소
해당 행의 모든 상자는 동일한 유형입니다.
숫자에 대한 행으로 시작하면 배열에 갑자기 문자를 넣을 수 없습니다.
메모리 할당
컴퓨터는 배열에 특정 메모리 덩어리를 할당합니다. 각 상자는 이 메모리 공간에 예약된 자리를 갖습니다.
프로그래밍 언어별 정적 배열
Topic | C | Java | Python |
---|---|---|---|
생성 및 초기화 | int staticArray[5] = {1, 2, 3, 4, 5}; | int[] staticArray = {1, 2, 3, 4, 5}; | a = np.arange(10) a.flags.writeable = False |
요소 접근 | int element = staticArray[2]; | int element = staticArray[2]; | element = a[0] |
파이썬에서는 정적 배열이 없습니다. 대신에 numpy의 array를 immutable로 변경할 수는 있습니다.
동적 배열 Dynamic Array
동적 배열이란?
동적 배열은 필요에 따라 확장하거나 축소할 수 있는 마법의 가방과 같습니다. 작은 가방으로 시작해서 더 많은 공간이 필요하면 가방이 자동으로 커집니다. 반대로, 물건을 꺼내면 가방이 줄어들어 공간을 절약할 수 있습니다.
동적 배열의 특성
동적 메모리 할당
정적 배열과 달리 동적 배열은 런타임 중에 크기가 변경될 수 있습니다. 더 많은 요소를 수용하기 위해 확장하거나 메모리를 절약하기 위해 축소할 수 있습니다.
다양한 유형의 요소
동적 배열은 더 유연하여 동일한 배열에 다양한 유형의 요소를 허용할 수 있습니다.
프로그래밍 언어별 동적 배열
python의 리스트, array, 자바의 arraylist, JS의 arr, cpp vector
파이썬의 동적 배열 list
작업 | 설명 | 예시 코드 |
---|---|---|
리스트 생성 | 대괄호와 요소를 사용하여 리스트 생성. | my_list = [1, 2, 3, 'a', 'b', 'c'] |
요소 접근 | 인덱싱을 사용하여 요소에 접근 (0부터 시작). | element = my_list[2] |
슬라이싱 | 리스트에서 일부 요소 추출. | sub_list = my_list[1:4] |
요소 추가 | 리스트 끝에 요소 추가. | my_list.append(4) |
요소 삽입 | 리스트의 특정 인덱스에 요소 삽입. | my_list.insert(2, 'x') |
리스트 확장 | 다른 리스트의 요소를 현재 리스트에 추가. | my_list.extend(['d', 'e', 'f']) |
요소 제거 | 값 또는 인덱스를 기반으로 리스트에서 요소 제거. | my_list.remove('a') del my_list[1] |
요소 pop | 특정 인덱스에서 요소를 제거하고 반환. | popped_element = my_list.pop(2) |
인덱스 찾기 | 값의 첫 번째 발생 위치의 인덱스 찾기. | index = my_list.index('b') |
멤버십 확인 | 값이 리스트에 존재하는지 확인. | is_present = 'x' in my_list |
카운트 | 값이 나타나는 횟수 세기. | occurrences = my_list.count('b') |
정렬 | 리스트를 오름차순 또는 내림차순으로 정렬. | my_list.sort() my_list.sort(reverse=True) |
뒤집기 | 리스트의 요소 순서 뒤집기. | my_list.reverse() |
복사 | 리스트의 얕은 복사 생성. | copied_list = my_list.copy() |
제거 | 리스트에서 모든 요소 제거. | my_list.clear() |
리스트 컴프리헨션 | 간결한 표현을 사용하여 새 리스트 생성. | squared_numbers = [x**2 for x in my_list] |
파이썬의 동적 배열 array
Python에서의 array는 다른 언어와 달리 정적 배열이 아닌 동적 배열 입니다.
array 모듈은 일반 리스트에 비해 더 컴팩트하고 메모리 효율적인 저수준 배열과 같은 데이터 구조를 제공합니다.
array 모듈 가져오기
from array import array
array 생성
array 클래스를 사용하고 데이터 유형에 대한 유형 코드를 지정하여 배열을 만들 수 있습니다. 다음은 정수 배열을 만드는 예입니다.
my_array = array('i', [1, 2, 3, 4, 5])
기본 연산
기본적으로 리스트 연산과 상당히 유사합니다.
작업 | 설명 | 예시 코드 |
---|---|---|
배열 생성 | array 클래스를 사용하여 배열 생성. | my_array = array('i', [1, 2, 3, 4, 5]) |
원소 접근 | 인덱싱을 사용하여 배열의 원소에 접근. | element = my_array[2] |
슬라이싱 | 배열에서 일부 원소 추출. | sub_array = my_array[1:4] |
요소 추가 | 배열 끝에 원소 추가. | my_array.append(6) |
요소 삽입 | 특정 인덱스에 원소 삽입. | my_array.insert(2, 7) |
배열 확장 | 다른 배열의 원소를 현재 배열에 추가. | another_array = array('i', [8, 9]) my_array.extend(another_array) |
요소 제거 | 값 또는 인덱스를 기반으로 배열에서 원소 제거. | my_array.remove(3) del my_array[1] |
요소 팝 | 특정 인덱스에서 원소를 제거하고 반환. | popped_element = my_array.pop(2) |
인덱스 찾기 | 값의 첫 번째 발생 위치의 인덱스 찾기. | index = my_array.index(4) |
요소 확인 | 값이 배열에 존재하는지 확인. | is_present = 5 in my_array |
카운트 | 값이 나타나는 횟수 세기. | occurrences = my_array.count(2) |
정렬 | 배열을 오름차순 또는 내림차순으로 정렬. | my_array.sort() my_array.sort(reverse=True) |
뒤집기 | 배열의 원소 순서 뒤집기. | my_array.reverse() |
복사 | 배열의 얕은 복사 생성. | copied_array = my_array.copy() |
클리어 | 배열에서 모든 원소 제거. | my_array.clear() |
remove
, index
, count
등의 작업은 원소를 찾지 못할 경우 예외를 발생시킬 수 있음에 유의 합니다.
데이터 타입
Python array
모듈에서는 문자 또는 문자열 데이터 유형이 직접 지원되지 않습니다. ‘array’ 모듈은 주로 숫자 데이터용으로 설계되었음에 유의해야 합니다.
Type Code | Data Type | Range | Example |
---|---|---|---|
b | Signed Char | -128 to 127 | array('b', [-128, 0, 127]) |
B | Unsigned Char | 0 to 255 | array('B', [0, 128, 255]) |
h | Short | -32,768 to 32,767 | array('h', [-32768, 0, 32767]) |
H | Unsigned Short | 0 to 65,535 | array('H', [0, 32768, 65535]) |
i | Int | -2,147,483,648 to 2,147,483,647 | array('i', [-2147483648, 0, 2147483647]) |
I | Unsigned Int | 0 to 4,294,967,295 | array('I', [0, 2147483648, 4294967295]) |
l | Long | -2,147,483,648 to 2,147,483,647 | array('l', [-2147483648, 0, 2147483647]) |
L | Unsigned Long | 0 to 4,294,967,295 | array('L', [0, 2147483648, 4294967295]) |
q | Long Long | -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 | array('q', [-9223372036854775808, 0, 9223372036854775807]) |
Q | Unsigned Long Long | 0 to 18,446,744,073,709,551,615 | array('Q', [0, 9223372036854775808, 18446744073709551615]) |
f | Float | Platform-dependent | array('f', [1.23, 4.56, 7.89]) |
d | Double | Platform-dependent | array('d', [1.23, 4.56, 7.89]) |
정적 배열 vs 동적배열
측면 | 정적 배열 | 동적 배열 |
---|---|---|
정의 | 선언 시에 크기가 고정됨. | 실행 중에 크기 조정 가능. |
장점 | 단순성 | 동적 크기 조정 |
예측 가능한 메모리 사용량 | 다양한 용도 | |
단점 | 크기 고정 | 복잡성 |
메모리 낭비 | 메모리 단편화 | |
오류 발생 가능성 | ||
사용 사례 | 크기가 알려진 상황에 적합. | 변화하는 데이터 크기에 대응이 필요한 경우. |