C/C++, Java 등의 언어에서 배열(Array)은 가장 널리 쓰이는 자료 구조 중 하나입니다. 이들 언어에서 배열은 동일한 데이터 타입을 가진 여러 요소의 집합으로 정의됩니다. 반면 Python에는 C 스타일 배열과 완전히 같은 내장 자료형이 없습니다. 리스트(List)와 튜플(Tuple) 역시 요소들의 집합이지만, 서로 다른 타입의 요소를 함께 담을 수 있다는 점이 배열과 다릅니다.
Python의 array 모듈은 C 타입 배열을 흉내 내는 기능을 제공합니다. 이 모듈은 'array' 클래스를 정의하며, 다음 생성자를 통해 배열 객체를 만들 수 있습니다.
array(typecode, initializer)
typecode 인자는 배열의 데이터 타입을 결정하며, initializer는 해당 타입과 일치하는 요소들로만 구성된 시퀀스여야 합니다.
다음 예제는 정수 배열 객체를 생성하는 코드입니다.
>>> import array
>>> arr = array.array('i', range(5))
>>> arr
array('i', [0, 1, 2, 3, 4])
>>> type(arr)
<class 'array.array'>
>>> array.typecodes
'bBuhHiIlLqQfd'
array 모듈의 typecodes 속성은 문자열을 반환하며, 문자열의 각 문자는 C 타입과 그에 대응하는 Python 타입을 나타내는 타입 코드입니다.
| 타입 코드 | C 타입 | Python 타입 |
|---|---|---|
| 'b' | signed char | int |
| 'B' | unsigned char | int |
| 'u' | Py_UNICODE | 유니코드 문자 |
| 'h' | signed short | int |
| 'H' | unsigned short | int |
| 'i' | signed int | int |
| 'I' | unsigned int | int |
| 'l' | signed long | int |
| 'L' | unsigned long | int |
| 'q' | signed long long | int |
| 'Q' | unsigned long long | int |
| 'f' | float | float |
| 'd' | double | float |
initializer 인자에는 바이트(bytes)류 객체도 전달할 수 있습니다. 아래 예제는 문자열의 바이트 표현으로부터 배열을 생성합니다.
>>> arr1 = array.array('b', b'Hello')
>>> arr1
array('b', [72, 101, 108, 108, 111])array 클래스가 제공하는 주요 메서드를 하나씩 살펴보겠습니다.
buffer_info() — 버퍼 정보 확인
배열 내용을 저장하는 데 사용 중인 버퍼의 현재 메모리 주소와 요소 개수를 (address, length) 형태의 튜플로 반환합니다.
>>> arr = array.array('i', [0, 1, 2, 3, 4])
>>> arr.buffer_info()
(2201141755144, 5)count() — 특정 요소 개수 세기
배열 안에서 특정 요소가 나타나는 횟수를 반환합니다.
>>> arr = array.array('i', [0, 1, 2, 3, 4])
>>> arr.count(2)
1extend() — 배열 확장하기
iterable의 항목들을 배열 끝에 추가합니다. 이때 iterable은 배열과 정확히 같은 타입 코드를 가져야 하며, 그렇지 않으면 TypeError가 발생합니다.
>>> arr = array.array('i', [0, 1, 2, 3, 4])
>>> arr1 = array.array('i',[10,20,30])
>>> arr.extend(arr1)
>>> arr
array('i', [0, 1, 2, 3, 4, 10, 20, 30])fromfile() — 파일에서 데이터 읽기
파일 객체로부터 n개의 항목(기계 값 형태)을 읽어 배열에 추가합니다.
다음 예제에서는 먼저 파일을 바이너리 쓰기 모드로 엽니다.
>>> file = open('test.txt','wb')
>>> file.write(b'Hello Python')
12
>>> file.close()이제 이 파일의 데이터를 배열 객체에 추가해 보겠습니다.
>>> a = array.array('i')
>>> file = open('test.txt','rb')
>>> a.fromfile(file,file.tell())
>>> a
array('i', [1819043144, 2035294319, 1852794996])append() — 항목 추가하기
새 항목을 배열의 끝에 추가합니다.
fromlist() — 리스트에서 항목 가져오기
리스트의 항목들을 배열에 추가합니다. for x in list: a.append(x)와 동일하게 동작합니다.
>>> a = array.array('i')
>>> a.append(10)
>>> a
array('i', [10])
>>> num = [20,30,40,50]
>>> a.fromlist(num)
>>> a
array('i', [10, 20, 30, 40, 50])insert() — 지정 위치에 삽입하기
지정한 위치 앞에 새 항목을 삽입합니다.
>>> a = array.array('i', [10, 20, 30, 40, 50])
>>> a.insert(2,25)
>>> a
array('i', [10, 20, 25, 30, 40, 50])pop() — 항목 꺼내기
주어진 인덱스의 항목을 배열에서 제거한 후, 그 값을 반환합니다.
>>> a = array.array('i', [10, 20, 30, 40, 50])
>>> x = a.pop(2)
>>> x
30
>>> a
array('i', [10, 20, 40, 50])remove() — 특정 값 삭제하기
주어진 값과 일치하는 첫 번째 항목을 배열에서 제거합니다.
>>> a = array.array('i', [10, 20, 30, 40, 50])
>>> a.remove(30)
>>> a
array('i', [10, 20, 40, 50])tofile() — 파일에 데이터 쓰기
쓰기 권한이 있는 파일 객체에 배열의 모든 항목을 기록합니다.
>>> a = array.array('i', [10, 20, 30, 40, 50])
>>> file = open("test.txt","wb")
>>> a.tofile(file)
>>> file.close()
>>> file = open("test.txt","rb")
>>> file.read()
b'\n\x00\x00\x00\x14\x00\x00\x00\x1e\x00\x00\x00(\x00\x00\x002\x00\x00\x00'대량의 숫자 데이터를 다룰 때는 리스트보다 array 모듈이 메모리를 훨씬 효율적으로 사용합니다. 타입이 고정된 수치 데이터를 저장하거나 파일 입출력 성능이 중요한 경우라면 array 모듈 활용을 고려해 보세요.