Python(파이썬): 시퀀스 자료형 분류 및 예제

Python(파이썬): 시퀀스 자료형 분류 및 예제
파이썬에 어떤 시퀀스 자료형들이 있고 이들의 특성들은 무엇인지 잘 알아야 원하는 순간 적절한 자료형을 사용할 수 있는 것 같다. 해당 포스트는 이전에 공부했던 파이썬 시퀀스 자료형의 분류와 예제를 정리하였다. 시퀀스 자료형이란 데이터가 순서대로 나열된 형식을 의미한다. (이때, 데이터가 순서대로 나열되었다는 뜻일 뿐 정렬되어있다는 의미는 아니다.) 리스트, 튜플 같은 것들이 대표적으로 시퀀스 자료형에 포함되는 것이다. 시퀀스 자료형은 인덱싱, 슬라이싱, len(), ‘+’연산자를 이용한 연결, ‘*’연산자를 이용한 반복, ‘in’ 키워드를 이용한 맴버 확인 등이 가능하다.

시퀀스 자료형 코드 예제

li1 = [1,2,3]
li2 = [2,3,4]
print('list의 인덱싱:', li1[0])
print('list의 슬라이싱:', li1[1:])
print('list의 +연산:', li1 + li2)
print('list의 *연산:', li1*2)
print('list의 요소 확인:', 2 in li1)
print('list의 요소 확인:', 10 in li1)

tuple1 = (1,2,3)
tuple2 = (2,3,4)
print('tuple의 인덱싱:', tuple1[0])
print('tuple의 슬라이싱:', tuple1[1:])
print('tuple의 +연산:', tuple1 + tuple2)
print('tuple의 *연산:', tuple1*2)
print('tuple의 요소 확인:', 2 in tuple1)
print('tuple의 요소 확인:', 10 in tuple1)

결과

list의 인덱싱: 1
list의 슬라이싱: [2, 3]
list의 +연산: [1, 2, 3, 2, 3, 4]
list의 *연산: [1, 2, 3, 1, 2, 3]
list의 요소 확인: True
list의 요소 확인: False
tuple의 인덱싱: 1
tuple의 슬라이싱: (2, 3)
tuple의 +연산: (1, 2, 3, 2, 3, 4)
tuple의 *연산: (1, 2, 3, 1, 2, 3)
tuple의 요소 확인: True
tuple의 요소 확인: False

참고로 딕셔너리나 set은 시퀀스 자료형이 아니기 때문에 슬라이싱, ‘+’, ‘*’연산이 되지 않는다. 딕셔너리 코드 예제를 보면 슬라이싱, ‘+’, ‘*’ 연산에서 오류가 발생하는 것을 확인 할 수 있다. (반면 딕셔너리에서는 key값에 대한 value를 출력하는 것과 요소를 확인하는 in 키워드는 사용할 수 있는 것을 볼 수 있다)

딕셔너리는 시퀀스 자료형이 아니다

dic1 = {1:'대기자1', 2:'대기자2', 3:'대기자3'}
dic2 = {3:'대기자3', 4:'대기자4', 5:'대기자5'}
print('dict의 인덱싱:', dic1[0])  # Error
print('dict의 인덱싱:', dic1[1])  # 대기자1
print('dict의 슬라이싱:', dic1[1:])  # Error
print('dict의 +연산:', dic1+dic2)  # Error
print('dict의 *연산:', dic1*2)  # Error
print('dict의 요소확인:', 3 in dic1)  # True
print('dict의 요소확인:', 10 in dic1)  # False

시퀀스 자료형 분류

자료형은 2가지 관점에서 분류할 수 있다.

  • 컨테이너 or Flat
  • 가변 or 불변

컨테이너 or Flat

컨테이너는 서로 다른 자료형을 포함 할 수 있다. 리스트, 튜플, 컬렉션, deque가 컨테이너에 속한다. 반면 Flat은 하나의 자료형만 포함 할 수 있다. str, bytes, bytearray, array.array, memoryview이 flat에 속한다.

아래 코드를 보면 컨테이너형인 리스트는 단일 객체형은 물론 다양한 객체형으로도 구성할 수 있는 것을 확인 할 수 있지만 Flat 자료형인 array.array 같은 경우 단일 객체형만으로만 구성할 수 있는 것을 볼 수 있다 (array.array는 첫 인자로 type code를 받아서 애초에 객체형을 지정한다. 아래 코드에서는 ‘I’로 type code를 입력해서 int으로 array안에 들어갈 수 있는 객체형을 지정한 것이다.)

import array

container_li1 = [1,2,3]
print('컨테이너형 리스트:', container_li1)
container_li2 = [1,2,3, '글자1', ['nested list'], {10}, (1,2)]
print('컨테이너형 리스트:', container_li2)
flat_array1 = array.array('I', [1,2,3])
print('Flat형 array:', flat_array1)
# flat_array2 = array.array('I', [1,2,3, '글자1', ['nested list'], {10}, (1,2)]) #TypeError
# print('Flat형 array:', flat_array2)

가변 or 불변

데이터가 변경 가능한 것을 가변형, 변경 불가능한 것을 불변형이라고 부른다. 가변형에는 list, bytearray, array.array, memoryview, deque이 있고 불변형에는 tuple, str, bytes이 있다.

아래 코드를 보면 가변형인 리스트는 변경이 가능하지만 불변형인 str은 변경이 불가능한 것을 볼 수 있다.

# Mutable list
li = [1,2,3,4]
li[0] = 10
print('리스트 요소 변경:', li)  # [10, 2, 3, 4]

# Immutable str
strs = 'ABCDE'
## Str의 인덱싱은 가능
print('String 인덱싱:', strs[0])  #A
## Str의 변경은 불가능
# strs[0] = 'Z'  # TypeError
# print('String 변경:', strs)

하지만 가변, 불변 개념을 모르고 사용하다가 해당 개념을 알게 되면 ‘이상하다? 불변형도 변경가능 한데?’라고 생각이 들 수 있다. 이 경우는 변경 된 것이 아니라 새롭게 할당 된 경우이다. 이는 id 함수를 이용하여 확인 할 수 있다.

불변 및 가변의 값 변경 코드

l = (10, 20, 25)
m = [10, 20, 25]

print('Immutable:', l, id(l))
print('Mutable:', m, id(m))

l *= 2
m *= 2

print('Immutable:',l, id(l))
print('mutable:',m, id(m))

결과

변수명은 동일하지만 동일 변수가 변경 된 것이 아니라 새롭게 할당된 것을 ID가 달라진 것을 통해 확인할 수 있다.

Immutable: (10, 20, 25) 2484879407808
Mutable: [10, 20, 25] 2484879085824
Immutable: (10, 20, 25, 10, 20, 25) 2484878561664
mutable: [10, 20, 25, 10, 20, 25] 2484879085824

Leave a Comment

목차