[Python] Data Types / Data Structure / Container (List, Tuple, Set, Dictionary) / mutable, immutable / hashable

jiggyjiggy·2022년 4월 3일
0
post-thumbnail

자료형(Data Type)마다 각각의 특색이 있습니다

따라서 각각의 자료구조(Data Structure)를 따로 외우기보다
자료구조가 어떤 타입의 자료형인지 알아둔다면 오래 기억할수있습니다

공식문서(Python Docs)에서 명시해둔대로 자주 쓰이는 자료구조(integer, float, set, dictionary, list, tuple, string)를 Type 별로 묶어서 도식화 해봤습니다


이 외에도 여러 자료구조와 여러 Type이 존재합니다 다루게 될 경우 블로그 링크를 추가해 두겠습니다 링크

https://docs.python.org/3/reference/datamodel.html
여러가지 data type 공식문서,
Python에서 type은 data model로 표현합니다



문자열 또한 Sequence Type 이지만 문자열 처리를 위해 맞춤화되었기에 엄밀하게 따지자면 Text Sequence Type 입니다

python built in types
https://docs.python.org/3/library/stdtypes.html#


여러개의 정보를 저장 할 때 가장 자주 쓰이는 list, tuple, set, dictionary만 뽑아왔습니다


Container

요소(element)에 여러 자료형을 쓸 수 있다!

Python에서는 특징적인 자료구조가 존재합니다

  • list
  • tuple
  • set
  • dictionary

이들의 특징은 container 라는 것인데요

Python에서 내장(Built-in) Container는 list, tuple, set, dictionary 가 있습니다.

Container 란
자기 자신의 자료형이 아닌 다른 자료형의 객체(Object)를 저장 할 수 있는 자료구조를 뜻합니다.

list_ = [["list"], (1, 2, 3), {"set"}, {"dict_in_dict_": "value"}]

이러한 특징으로 인해 다른 프로그래밍 언어에 비해 Python의 간편함이 매우 올라갔습니다


몇 개 빼고~~

하지만 예외가 있는데요

요소에 모든 자료형을 쓸 수 있는 것은 아닙니다.

아래와 같이 code를 작성하면

list_ = [["list"], (1, 2, 3), {"set"}, {"dict_in_dict_": "value"}]

tuple_ = (["list"], (1, 2, 3), {"set"}, {"dict_in_dict_": "value"})

set_ = {["list"], (1, 2, 3), {"set"}, {"dict_in_dict_": "value"}}

dict_ = {
  ["list"] : ["list"],
  (1, 2, 3) : (1, 2, 3),
  {"set"} : {"set"},
  {"dict_in_dict_": "value"} : {"dict_in_dict_": "value"}
}

오류가 발생합니다

Traceback (most recent call last):
  File "main.py", line 5, in <module>
    set_ = {["list"], (1,2,3), {"set"}, {"dict_in_dict_": "value"}}
TypeError: unhashable type: 'list'

list는 unhashable type이라고 나오네요


TypeError: unhashable type: 'list'

set은 hashable 객체만 요소로 할당할 수 있습니다

list, set, dictionary 객체는 unhashable 입니다
tuple 객체는 hashable 입니다

  • hashable : tuple, ...
  • unhashable : list, set, dictionary, ...

dictionary의 요소의 key 또한 hashable 객체만 할당할 수 있습니다

따라서 가능한 할당은 다음과 같습니다

list_ = [["list"], (1, 2, 3), {"set"}, {"dict_in_dict_": "value"}]

tuple_ = (["list"], (1, 2, 3), {"set"}, {"dict_in_dict_": "value"})

set_ = {(1, 2, 3)}	# 수정된 부분

dict_ = {
  1 : ["list"],	# 수정된 부분
  (1, 2, 3) : (1, 2, 3),
  2 : {"set"},	# 수정된 부분
  3 : {"dict_in_dict_": "value"}	# 수정된 부분
}
	수정한 dictionary의 key는 hashable type인 int 객체를 사용했습니다
    

이 블로그에서 hashable이란 유일한 1개의 값이 유일한 1개의 값을 가리키는 것이라 생각하면 됩니다

dictionary를 예시로, 만약 중복되는 값이 key로 존재한다면 도착지점을 어디로 해야할지 컴퓨터는 모릅니다!
dict_ = {
  1 : ["list"],	
  1 : (1, 2, 3),
  1 : {"set"},	
  1 : {"dict_in_dict_": "value"}	
}
dict_[1]	# ????????????????
"뭔말인지 알지?"
"ㅋㅋ 모르지"

hashable 에 관한 개념에 관한 블로그 글 링크


code를 통해나오는 에러 메시지를 통해 자료구조의 특징을 알아보았습니다

그러나 개별적인 예시로 정보의 파편을 기억하려고 하면 매번 까먹기 쉽상입니다

전체적인 자료형 카테고리를 알아두고 해당 자료형의 특징을 알아두는 것이 효율적인 공부방법이 될 것입니다


자료형의 특징

CRUD 관점

자료형마다 갖고 있는 특징이 여러개가 존재합니다
이번 블로그에서는
주제가 "자료구조"이므로 CRUD의 관점에서에 관해 필요한 정보들을 정리해보겠습니다

R: Read 에 관해서 먼저 생각해 보겠습니다

Data Type의 특징과 깊은 관련이 있습니다

Sequence Type은 index가 핵심 개념입니다: 저장된 데이터 요소자체의 위치를 통해 찾을 수 있습니다
Set Type, Mapping Type은 hashable에 대해 관련있습니다: 유일한 값으로 저장값을 찾기 위해서 입니다

따라서 위와 같은 특징으로 자료구조를 C: Create 하는 것 입니다.


저장값을 Read 가능하므로

나머지 U: Update, D: Delete관점에서 알아보겠습니다


Update, Delete에 관해서는
차이점을 알기 위해선 mutable과 immutable에 대한 개념을 알아야 합니다

다만 이 블로그에선 영어의 의미대로 "수정가능"한지 불가능한지 아는 정도면 충분합니다


mutable, immutable 에 관한 개념에 관한 블로그 링크
shallow copy, deep copy를 통해 identity, equality에 관한 개념을 정리하였습니다



자료형 마다의 특징을 다시 정리해 보겠습니다

저장값 접근 (Read)

  • sequence type: index를 통해 요소에 접근 합니다

  • set type: 요소를 hashable한 객체만 저장하는 특징이 있습니다. 때문에 객체(요소)의 hash 함수를 통해 요소에 접근합니다

  • mapping type: 요소의 key는 hashable 객체만 가능합니다. 때문에 객체(key)의 hash 함수를 통해 요소의 값(value)에 접근합니다

저장값 생성 (Create)

접근의 관점대로 생성이 되는 것입니다

저장값 수정 (Update, Delete)

  • mutable type: 동일 객체로써 수정이 가능

  • immutable type: 동일 객체로써 수정이 불가능


자료구조마다 다시 정리해 보겠습니다

list

  • Sequence Type 객체입니다

    • 때문에 index를 통해 요소에 접근 합니다
  • mutable 객체입니다

    • 때문에 동일 객체로써 수정이 가능합니다
list_ = [["list"], (1, 2, 3), {"set"}, {"dict_in_dict_": "value"}]

tuple

  • Sequence Type 객체입니다

    • 때문에 index를 통해 요소에 접근 합니다
  • immutable 객체입니다

    • 때문에 동일 객체로써 수정이 불가능합니다
tuple_ = (["list"], (1, 2, 3), {"set"}, {"dict_in_dict_": "value"})

list와 tuple의 메모리 사용량에 관한 블로그 링크

메모리 사용량이 적고 수정하지 않아도 된다면 tuple로 할당해주도록 합시다


Set

  • Set Type 객체입니다
    set type은 요소들로 hashable한 객체만 저장하는 특징이 있습니다.

    • 때문에 객체(요소)의 hash 함수를 통해 요소에 접근합니다
    • 때문에 요소마다 다른 값이 필요합니다 (중복이 불가능합니다)
  • mutable 객체입니다

    • 때문에 동일 객체로써 수정이 가능합니다
set_ = {(1, 2, 3)}	# 수정된 부분

dictionary

  • Mapping Type 객체입니다.
    Mapping Type은 요소의 key는 hashable 객체만 가능합니다

    • 때문에 객체(key)의 hash 함수를 통해 요소의 값(value)에 접근합니다
    • 따라서 요소의 key마다 다른 값이 필요합니다 (중복이 불가능합니다)
  • mutable 객체입니다

    • 때문에 동일 객체로써 수정이 가능합니다
dict_ = {
  1 : ["list"],	
  (1, 2, 3) : (1, 2, 3),
  2 : {"set"},	
  3 : {"dict_in_dict_": "value"}	
}

dictionary에서 자주 하는 착각

여러 블로그를 보면 dictionary에서 자주 하는 착각이
dictionary의 key를 immutable 객체를 써야한다고 표현해둔 곳이 많습니다. 일반적인 쓰임에서는 맞는 말이지만
하지만 정확하게는 dictionary의 key를 hashable 객체를 써야한다고 표현하는 것이 맞는 표현입니다


무엇을 해야할지 알 수 있다

자료형의 특징을 알고 있다면

자료구조만 보다보면 헷갈릴때가 많습니다.
그러다보면 "뻘 짓"을 하게되는 경우가 종종 생기게 됩니다.

단순하게는 set의 요소로 list 객체를 넣으려고 고생하거나
더 나아가서는 쉽게 해결가능한 로직이, 프로그래밍적으로 꽤 돌아갈 수 있습니다.


자료형의 특징을 잘 몰라서 쉬운길을 냅두고 프로그래밍적으로 꽤나 돌아가본 경험이 궁금하시다면 아래의 링크를 눌러주세요
String과 for문 블로그 링크


하지만 자료형의 특징을 기억해두고 자료구조를 사용하다보면 Python의 의도대로, 쉽고 강력한 프로그래밍을 할 수 있을 것입니다 (특히, 자료 검색 시, 공식문서에서 의미하는 바도 잘 이해할 수 있고 적용이 쉬워지는 걸 경험할 수 있습니다)

효율성

자료형마다의 특징을 공부해보니 어떠신가요?

자료구조마다 개별적인 특징을 모두 외우는 것보다
자료형에 따른 특징을 기억해두니

모든걸 외우지 않아도 어떤 기능이 존재하는지, 유추할 수 있지 않으신가요?

자료형의 특징에 따라 합리적인 기능이 있다면 객체의 method로 구현되어있을 겁니다
생각나는 method는 해당 객체 file에 들어가서 보셔도 되고 구글링을 통해 알아내도 됩니다

마지막 질문을 드리며 마쳐봅니다

Q.
tuple 요소의 일부분을 갖고오고 싶다면 어떻게 하시겠습니까?

A.
Sequence Type
index라는 특징으로 특정 위치에서 특정위치까지 쉽게 지정할수 있습니다 : slicing
또한 immutable 하기 때문에 slicing으로 새로운 객체로써 새로 할당됩니다
Python tuple slicing 으로 구글링 해보면
tuple[start:end:step] 으로 간단하게 표현할 수 있겠네요

profile
궁금증 주도 공부 / 원리 파고들기 / 경험에 기반한 블로그

0개의 댓글