[파이썬 자료구조] 배열

말하는 감자·2024년 8월 13일
1

파이썬 자료구조

목록 보기
1/5
post-thumbnail

안녕하세요.

저는 인공지능 개발자 (or 연구자)를 희망하는 취준생입니다.

파이썬을 주로 활용하다보니 자료구조를 파이썬으로 설명하고 구현하는 내용을 velog에 기록하려고 합니다. 또한 이 내용들은 코딩테스트를 중점으로 하여 공부한 내용들입니다.

오늘은 배열입니다!.


1. 배열 (Array)

  • 데이터를 나열하고, 각 데이터를 인덱스에 대응하도록 구성한 데이터 구조
  • 파이썬에서는 리스트 타입이 배열 기능을 제공함
    • 단, 리스트가 배열과 같은 의미는 아님 (밑에서 내용 설명)

1.1 배열은 왜 필요할까요?

  • 같은 종류의 데이터를 효율적으로 관리하기 위해 사용합니다.
  • 같은 종류의 데이터를 순차적으로 저장하기 위해 사용합니다.
  • 장점:
    • 빠른 접근 기능
      • 첫 데이터의 위치에서 상대적인 위치로 데이터 접근 (인덱스 번호로 접근)
  • 단점:
    • 데이터 추가/삭제의 어려움
      • 미리 최대 길이를 지정해야 함

2. 파이썬과 배열

파이썬에서는 리스트로 배열의 기능을 어느정도 구현할 수 있습니다. 하지만 배열의 완전한 의미 및 기능이 리스트와 동일하지 않습니다.

2.1 리스트란?

리스트는 파이썬에 내장된 데이터 구조로 items의 collection을 가집니다.

  • 리스트의 아이템들은 대괄호로 묶입니다.
    • [item1, item2, item3,… , ]
  • 리스트는 정렬되어 있습니다.
    • 인덱스로 각 아이템에 접근이 가능합니다.
  • 리스트는 변경 가능합니다.
    • 추가 및 제거가 가능합니다.
  • 중복이 가능합니다.
    • [item1, item1]
  • 리스트는 여러 가지 데이터 타입이 가능합니다.
    • [1, ‘2’, [1,2,3]]

코드로 예시를 살펴보겠습니다.

a = [1, '1',(1,2),'hi',[1,2,3]]
print(a) # [1, '1', (1, 2), 'hi', [1, 2, 3]]
print(type(a)) # <class 'list'>

2.2 파이썬에서 배열이란?

array module이나 numpy module을 통해 완전한 배열의 기능을 구현할 수 있습니다.

리스트가 가졌던 특징들처럼 대괄호, 정렬, 변경 기능, 중복이 가능합니다.

Array module

import array as arr
array_1 = arr.array("i", [2, 4, 6, 8])
print(array_1) # array('i', [2, 4, 6, 8]) 
print(type(array_1)) # <class 'array.array'>

파이썬의 array module은 모든 배열의 원소들이 같은 데이터 타입일 것을 요구합니다.

여기서 “i”부분은 array_1의 원소들이 다 정수인 것을 나타냅니다.

(사실 array 모듈을 써본적이 없습니다..)

Numpy

import numpy as np

# Mixed types example
array_1 = np.array([1, 2.5, True])  # 결과: [1.  2.5 1. ] dtype=float
array_2 = np.array([1, 2.5, "hello"])  # 결과: ['1' '2.5' 'hello'] dtype='<U32'
array_3 = np.array([1, 2.5, complex(2, 3)])  # 결과: [1. +0.j 2.5+0.j 2. +3.j] dtype=complex

NumPy에서 배열의 요소들이 서로 다른 데이터 타입을 가질 때, NumPy는 모든 요소를 공통된 데이터 타입으로 변환합니다. 이때 타입 변환은 다음과 같은 우선순위에 따라 이루어집니다:

  • Boolean (bool): 최하위 우선순위를 가지며, 모든 데이터 타입으로 변환될 수 있습니다. 예를 들어, TrueFalse는 숫자나 문자열로 변환될 수 있습니다.
  • Integer (int): 정수형 데이터는 그보다 상위 타입인 부동소수점(float) 또는 복소수(complex) 타입으로 변환될 수 있습니다.
  • Unsigned Integer (uint): 부호 없는 정수형 데이터는 정수형과 유사하게 다루어지지만, 양수의 범위가 더 넓습니다. 이 타입은 일반적인 정수형이나 부동소수점으로 변환될 수 있습니다.
  • Floating Point (float): 부동소수점 숫자는 복소수로 변환될 수 있습니다.
  • Complex (complex): 복소수는 가장 높은 우선순위를 가지는 숫자형 타입입니다. 정수형이나 부동소수점 숫자가 포함된 배열에 복소수가 추가되면, 모든 요소가 복소수로 변환됩니다.
  • String (str): 문자열은 숫자형 타입보다 높은 우선순위를 가지며, 배열에 문자열이 포함되면 숫자나 불리언 등 다른 타입의 요소들도 모두 문자열로 변환됩니다. NumPy는 가장 길이가 긴 문자열에 맞추어 다른 요소들을 문자열로 변환합니다.
  • Object (object): 객체 타입은 가장 높은 우선순위를 가지며, 배열에 다양한 타입의 Python 객체가 포함될 때 사용됩니다. 이 타입은 다른 모든 타입보다 우선순위가 높습니다.

따라서 우선순위는 다음과 같습니다:

객체 > String > Complex > Floating > Integer > Boolean

2.3 리스트와 배열의 차이

Python에서 배열(array)과 리스트(list)는 모두 여러 개의 요소를 저장할 수 있는 데이터 구조이지만, 이 두 가지는 여러 가지 면에서 차이가 있습니다. 주요 차이점을 아래와 같이 정리할 수 있습니다:

1. 데이터 타입

  • 리스트 (List): Python의 리스트는 이종 데이터 타입(heterogeneous data types)을 허용합니다. 즉, 리스트의 요소들은 서로 다른 데이터 타입을 가질 수 있습니다.
    my_list = [1, "Hello", 3.14, True]
    
  • 배열 (Array): 배열은 동종 데이터 타입(homogeneous data types)만 허용합니다. 배열에 있는 모든 요소는 동일한 데이터 타입을 가져야 합니다. Python의 array 모듈이나 NumPy 배열을 사용할 때 배열의 데이터 타입이 통일되어야 합니다.
    import array as arr
    my_array = arr.array('i', [1, 2, 3, 4])
    

2. 성능

  • 리스트 (List): 리스트는 일반적으로 유연하고, 다양한 타입의 요소를 저장할 수 있지만, 데이터의 크기나 복잡성에 따라 성능이 떨어질 수 있습니다. 특히, 대규모 연산이나 고성능 계산에서는 비효율적일 수 있습니다.
  • 배열 (Array): 배열은 고정된 데이터 타입을 가지기 때문에, 메모리 사용량이 더 적고, 특히 대규모 수치 계산에서 성능이 더 좋습니다. NumPy 배열은 대규모 데이터 처리를 위한 고성능 연산을 지원합니다.

3. 모듈과 지원 기능

  • 리스트 (List): 리스트는 Python의 내장 데이터 구조로, 별도의 모듈 없이 사용할 수 있습니다. 리스트는 다양한 메서드(append, insert, pop 등)를 제공하여 데이터를 쉽게 추가, 제거, 수정할 수 있습니다.
  • 배열 (Array): 배열은 기본적으로 Python의 array 모듈이나 NumPy 라이브러리를 사용해야 합니다. 특히, NumPy는 배열과 관련된 다양한 고성능 수치 연산 기능을 제공합니다.

4. 사용 목적

  • 리스트 (List): 리스트는 다양한 데이터 타입을 포함할 수 있기 때문에, 일반적인 데이터를 저장하고 처리하는 데 매우 유용합니다. 리스트는 여러 종류의 데이터를 함께 저장하거나, 데이터 구조를 생성하는 데 자주 사용됩니다.
  • 배열 (Array): 배열은 주로 수치 연산이나 대규모 데이터 처리를 위해 사용됩니다. NumPy 배열은 과학적 계산이나 데이터 분석에서 자주 사용되며, 행렬 연산, 통계 계산 등에서 강력한 성능을 제공합니다.

5. 유연성

  • 리스트 (List): 리스트는 크기나 요소의 데이터 타입이 고정되지 않아서 매우 유연하게 사용할 수 있습니다. 요소를 추가하거나 제거하는 것이 자유롭습니다.
  • 배열 (Array): 배열은 요소의 데이터 타입이 고정되어 있기 때문에, 유연성이 떨어지지만, 이 덕분에 메모리 관리가 더 효율적입니다. 일반적으로 배열의 크기도 고정되어 있으며, 크기를 변경하려면 새로운 배열을 만들어야 합니다.

요약

  • 리스트는 일반적인 데이터 저장 및 처리에 적합하며, 다양한 데이터 타입을 지원하고 유연성이 높습니다.
  • 배열은 수치 연산 및 대규모 데이터 처리에 적합하며, 동일한 데이터 타입을 가진 요소들로 이루어져 있어 메모리 효율이 높고, 성능이 더 우수합니다.

각자의 목적에 맞게 리스트와 배열을 선택해서 사용하는 것이 중요합니다.

But!

Python에서는 리스트(list)가 매우 유연하고 강력한 기능을 제공하기 때문에, 많은 경우에 리스트가 배열처럼 사용됩니다. 특히 Python은 내장된 리스트 타입을 통해 동적 배열의 기능을 제공하며, 이를 활용해 다양한 데이터를 쉽게 저장하고 조작할 수 있습니다.

Python에서의 리스트와 배열의 혼용

Python에서는 일반적으로 리스트를 사용하여 배열의 역할을 수행합니다. 리스트는 다양한 데이터 타입을 포함할 수 있고, 크기가 동적으로 조정될 수 있기 때문에, 많은 상황에서 배열처럼 사용할 수 있습니다.

my_list = [1, 2, 3, 4, 5]  # 배열처럼 사용 가능한 리스트

진정한 배열의 필요성

하지만, 엄밀한 의미에서 "배열"은 고정된 데이터 타입을 가지며, 보통 수학적 계산이나 대규모 데이터 처리에서 더 효율적인 메모리 사용과 성능을 제공합니다. 이와 같은 요구가 있을 때는 Python의 내장 array 모듈이나, 더 고급 기능을 제공하는 NumPy 라이브러리를 사용하여 실제 배열을 구현합니다.

import array as arr

# array 모듈을 사용한 배열 생성
my_array = arr.array('i', [1, 2, 3, 4, 5])

또는, NumPy를 사용한 배열:

import numpy as np

# NumPy 배열 생성
np_array = np.array([1, 2, 3, 4, 5])

결론

실제로 Python에서는 리스트가 배열처럼 널리 사용되지만, 기술적으로 리스트는 동적 배열의 기능을 갖춘 데이터 구조입니다. "배열"이라는 용어가 사용될 때, 사람들은 종종 Python의 리스트를 언급하는 경우가 많습니다. 하지만, 엄밀하게 고정된 데이터 타입과 성능을 요구하는 경우, array 모듈이나 NumPy 라이브러리를 사용하여 진정한 의미의 배열을 사용할 수 있습니다.

따라서, 일반적인 Python 프로그래밍 (eg. 코딩테스트)에서는 리스트가 배열처럼 사용되며, 특수한 상황에서는 arrayNumPy 배열을 사용하게 됩니다.

읽어주셔서 감사합니다!

References

https://learnpython.com/blog/python-array-vs-list/
https://statanalytica.com/blog/python-array-vs-list/

profile
할 수 있다

0개의 댓글