파이썬 데이터 타입
목차
프로그램을 작성한다는 것은 어떤 데이터를 가지고 무엇인가 동작을 처리한다고 일반화해서 말할 수 있습니다. 예를 들어 계산기는 숫자를 입력하고 연산자 버튼을 클릭한 후 다시 숫자를 하나 더 입력하면 수식이 계산되어 답이 나옵니다. 아주 간단한 원리이지만 우리가 만드는 복잡한 파이썬 프로그램도 따지고 보면 같은 원리로 동작합니다. 컴퓨터(computer)란 계산기(calculator)이니까요. 물론 컴퓨터는 좀 더 복잡한 계산을 하여 더 많은 일을 할 수 있는 진화한 계산기 입니다.
데이터의 종류라는 것은 제한이 없습니다. 그것이 사람의 키를 나타내건, 학교 급식에서 사용하는 고기의 중량을 나타내건 모두 데이터입니다. 사람의 이름도 데이터입니다. 흔히 숫자만 데이터라는 인식이 있는데 그것도 맞는 말입니다. 이름이나 명칭 같은 문자열도 데이터이고 문자열은 유니코드 변환에 의하여 숫자로 나타낼 수 있습니다. (컴퓨터는 문자를 숫자로 인식한다)
프로그래밍 언어를 학습함에 있어서도 데이터에 대한 진도를 다 나가면 50% 이상을 배웠다 할 수 있을 정도로 큰 주제입니다. 이 데이터 타입은 어렵게 배우면 한참 어렵고 쉽게 생각해서 사용하면 또 쉽다고 할 수도 있습니다. 잠깐 그 이야기를 해보겠습니다.
아마 컴퓨터공학을 전공한 사람이라면 C언어의 데이터 타입을 배운 적이 있을 겁니다. C언어는 고수준언어(high level language)라고 보는 사람도 있고 저수준 언어(low level language)라고 말하는 사람도 있는데 어느 정도 상대적인 개념입니다. 여기서는 C언어를 저수준 언어로 보고 데이터 타입에 대하여 이야기 해보겠습니다.
저수준 언어라는 것은 기계적인 부분까지 컨트롤을 해줘야 합니다. 컴퓨터가 0과1 숫자만 사용해서 연산을 한다는 것은 거기서 끝나지가 않습니다. 일단 정수형 integer 부터 보면 몇 비트를 사용할 것 인가? 이것을 CPU가 작동하는 원리에 따라 데이터 타입을 선언해야 합니다.
C언어에서 int var 선언의 의미는 32비트 부호있는 정수형 (대략 -21억~+21억 범위의 숫자)로 데이터의 타입을 사용하겠다는 뜻 입니다. 당연히 32비트 정수형은 같은 32비트 정수형과 연산할 수 있습니다. 결과값도 32비트 정수를 벗어나지 않는데 그것까지 프로그램 설계 시점에 고려를 해야 합니다. 그래서 C언어 프로그램을 만들 때는 대부분의 시간을 데이터를 설계하는데 할애합니다. 메모리를 절약하는 최적의 데이터 타입은 무엇인가? 오버플로(overflow)는 어떻게 방지할 것 인가? 이런 것들은 어떻게 보면 응용 프로그램의 본질과는 좀 거리가 있는 시스템 적인 문제일 수 있습니다.
프로그램을 만드는 것은 건설에 비유할 수 있습니다. (build) 집을 하나 지으려면 각 분야의 전문가들이 필요한데 데이터 타입부터 시작하는 것은 혼자서 토목공사부터 인테리어 마감까지 직접 하는 느낌입니다. 컴퓨터 프로그래밍의 초창기에는 한 사람이 모든 프로그램을 만드는 경우가 종종 있었습니다. 리눅스 커널 같은 복잡한 시스템 프로그램도 리누즈 토발즈 한 사람이 만들었습니다. 전세계 히트한 블록 게임인 테트리스도 소련의 프로그래머가 혼자서 만들었다고 알려져 있죠. 과거에는 그런게 가능했고 물론 지금도 가능합니다만, 포인트가 다르긴 합니다.
요즘도 1인 개발자가 많이 있지만 그들이 사용하는 오픈소스 프레임워크와 툴(유니티 등)의 기능은 그때보다 훨씬 뛰어납니다.
파이썬도 마찬가지 입니다. 사실 파이썬으로 응용 프로그램을 개발하는데 데이터 타입을 빠삭하게 다 배워서 시작할 필요는 없습니다. 대부분 쓸만한 데이터 타입 즉 파이썬 안에 있는 내장 객체가 다 해결해주기 때문입니다. 고성능의 수치 연산에 필요한 객체와 함수는 numpy 패키지를 사용하면 해결이 됩니다. 이런 것들을 원초적인 데이터 타입을 만들라고 하면 못하겠지만 이미 구현이 되어 있고 많은 사용자들이 있는 외부 라이브러리를 사용하면 거의 다 해결이 됩니다.
C언어라면 학습 방법이 완전히 다를 것 입니다. 정수형, 문자형, 실수형 등 C언어는 뒤로 갈 수록 데이터 타입이 너무 많이 나와서 그것을 이해하는데 들어가는 시간만 한참 걸립니다. 예를 들어서 문자형은 char 입니다. 그런데 여기에 한글은 저장이 안됩니다. 그렇다면 16비트나 32비트 문자형을 사용해야 하는데 이 데이터 타입 부터가 여러개가 나옵니다. 수십개 이상의 데이터 타입 중에 어떤 것을 사용할 것인가 따지는 것 부터가 일입니다.
하지만 파이썬은 그냥 myString = ‘안녕하세요’ 이게 끝입니다. 이것은 파이썬 컴파일러에 타입 추정 기능을 사용하기 때문입니다. 파이썬은 컴파일을 하지만 기본적으로 인터프리터 언어로 한 줄을 읽고 한 줄을 실행시킵니다. 즉 myString = ‘안녕하세요’ 이 라인을 실행하기 전에는 이게 무슨 데이터 타입인지 모릅니다. 실행이 될 때 (runtime) 즉시 이 한줄 코드를 읽고 ” 따옴표 안에 있는 내용을 확인하여 타입을 추정하고 그에 따른 메모리를 할당합니다. 이는 type 함수로 확인할 수 있습니다. 이런 방식은 데이터 타입의 사용에 유연하게 동작하며 동적 타이핑(dynamic typing) 이라고 합니다. (반대는 정적 타이핑 – static typing)
파이썬 데이터 타입 소개
아래 코드는 숫자형과 문자열의 예제입니다. 숫자는 정수는 int 클래스, 실수는 float 클래스, 문자열은 str 클래스입니다. 파이썬의 변수는 객체로 각각에 data type 이 지정되어 있습니다. 이렇게 기본적인 타입은 내장객체로 사용할 수 있습니다.
myInteger = 10 myFloat = 99.9 myString = '문자열' print(myInteger) print("- type: ", type(myInteger)) print(myFloat) print("- type: ", type(myFloat)) print(myString) print("- type: ", type(myString))
(결과창) 10 - type: <class 'int'> 99.9 - type: <class 'float'> 문자열 - type: <class 'str'>
다음은 리스트와 튜플입니다. 리스트는 배열(array)처럼 인덱스를 사용하여 리스트의 요소에 접근할 수도 있고 리스트 안에 리스트나 객체, 함수의 참조도 포함할 수 있고 다중 리스트를 만들 수도 있는 등 매우 강력한 자료구조입니다. 웬만한 코드를 작성할 때 이 리스트만 가지고도 많은 일을 할 수 있습니다.
파이썬은 대체로 느리다는 단점이 있지만 내장 객체 타입인 리스트는 내부적인 스피드를 높이도록 C언어로 설계되어 있기 때문에 빠르게 작동합니다.
리스트와 튜플은 거의 비슷해 보이지만 튜플은 불변성(immutable)을 갖습니다. 리스트는 내부의 요소를 추가하거나 수정하는 것이 가능하지만 튜플은 한번 생성되면 그 값을 바꿀 수 없도록 하여 일종의 상수 변수 같은 방식으로 사용할 수 있습니다. 자세한 내용은 개별 주제를 다루는 포스팅에서 다루겠습니다.
myList1 = [1,2,3,4,5] myList2 = ['apple', 'mango', 'kiwi'] myTuple1 = (1,3,5,7,9) myTuple2 = ('하나','둘','셋') print(myList1) print(myList2) print(myTuple1) print(myTuple2)
리스트와 튜플은 인덱스를 사용할 수 있는 씨퀀스(sequence)입니다. 반면 딕셔너리는 인덱스가 아니라 키값을 사용합니다. key – value 저장 방식으로 key로 value 에 접근합니다. 자바스크립트의 json 파일이 생각나는 구조입니다. 딕셔너리(dictionary)도 해당 주제의 포스팅에서 상세하게 다룹니다.
일반적으로 리스트, 튜플, 딕셔너리를 많이 사용하게 되는데 자바 언어의 콜렉션(Collection) 프레임워크나 C++의 STL Container 와 같은 자료 구조임을 알 수 있습니다. 어떤 프로그램을 작성하더라도 기본 변수만 가지고는 한계가 있으니까 자료구조가 필요합니다. 파이썬의 이 세가지 자료 타입은 유연하고 강력하면서도 사용법이 쉽습니다.
myDict1 ={ 'name': 'Han Gil Soo', 'age' : 17, 'job' : 'student', 'hobby' : ['영화관람', '자전거타기']} print(myDict1) print(myDict1['name']) print(myDict1['age']) print(myDict1['job']) print(myDict1['hobby']) print(myDict1['hobby'][0]) print(myDict1['hobby'][1])
{'name': 'Han Gil Soo', 'age': 17, 'job': 'student', 'hobby': ['영화관람', '자전거타기']} Han Gil Soo 17 student ['영화관람', '자전거타기'] 영화관람 자전거타기
그 밖의 내장객체
이외에도 파일 타입(텍스트/바이너리) 객체나 세트(SET – 집합과 비슷한 자료구조), 파이썬 기본 배포판의 내장 클래스와 함수가 있습니다. 여기서는 여러가지 내장 객체 타입이 있다는 정도만 소개하도록 하겠습니다.
요약
파이썬을 배우기 시작할 때 어느 정도 큰 그림을 놓고 보면 내장 객체의 사용법을 배우는데 얼마나 시간이 걸릴지 가늠할 수 있습니다. 동적 타이핑인 것도 그렇지만 파이썬 자체의 설계 철학이 간결하기 때문에 사용자들은 최대한 빨리 자신의 목적한 지점에 도달할 수 있을 것 입니다.
자바만 해도 변수 타입에 대한 내용이 적지 않고 콜렉션 프레임워크(Collection Framework) 까지 진도를 나가려면 한참이 걸리는데 파이썬은 처음부터 리스트와 튜플, 딕셔너리를 사용할 수 있습니다. 자바로 따지면 콜렉션 프레임워크를 바로 가져다가 사용하는 느낌입니다. 뿐만 아니라 파이썬은 이 세개의 자료구조를 이용하여 사용자 정의 자료구조를 만들 수 있습니다. 스택, 큐, 링크드 리스트 등도 내장객체를 사용하여 쉽게 만들 수 있습니다. 물론 처리 속도가 중요한 프로그램에는 성능적 이슈가 있겠지만 처리 성능이 중시되는 프로젝트 라면 애초에 파이썬을 선택하지 않았을 겁니다. 또 파이썬은 다른 언어로 만들어진 프레임워크나 라이브러리의 바인딩도 많기 때문에 처리 성능 이슈들은 점차 해소가 되고 있습니다.
파이썬이 다른 언어에 비하여 사용하기 쉽다는 인상은 내장 객체부터 받을 수 있습니다.
외부 참고 문서
Built-in Types — Python 3.10.0 documentation