본문 바로가기
파이썬/주식 자동매매

Python 키움API 자동매매프로그램 개발-8.Python 기초편 튜플, 리스트 사용 패킹 언패킹

by 행복론자 2021. 1. 22.

시리즈 이전글입니다.

2021/01/22 - [파이썬/주식 자동매매] - Python 키움API 주식자동매매프로그램 개발 - 7.Python 기초편 문자열 사용

 

 

지금까지는 하나의 변수에 하나의 값만 저장했습니다. 하지만 값이 서로 연관성이 있다거나 연산의 결과를 모아야할 때는 값들의 묶음이 필요할 수 있습니다.

예를 들어 삼성전자의 2020년 1월부터 12월까지의 월말 종가를 다음처럼 저장한다고 해보겠습니다. 

samsung_1 = 40000
samsung_2 = 45000
samsung_3 = 50000
samsung_4 = 55000
samsung_5 = 60000
samsung_6 = 60500
samsung_7 = 61000
samsung_8 = 67000
samsung_9 = 76000
samsung_10 = 80000
samsung_11 = 82000
samsung_12 = 83000



지금은 변수가 12개 뿐이지만 변수에 저장할 값이 많아질수록 선언해야할 변수의 양이 많아집니다.

여기서 튜플과 리스트라는 데이터 타입을 통해 데이터들을 하나로 묶을 수 있습니다.

튜플 = (값, 값, 값, 값..)
리스트 = [값, 값, 값, 값..]

 

 

이렇게 순서를 주어 값을 저장하는 튜플과 리스트라는 데이터 타입을 시퀀스(Sequence) 자료형이라고 합니다.(앞서 배운 문자도 시퀀스 자료형이기는 합니다.) 

여기서 저장할 값들의 데이터 타입 제한은 없습니다.

숫자나 문자 논리형 등 필요한 데이터를 넣어 ()나 []를 사용하여 선언하면 됩니다.

a = (1, "Hello", 1/4, True)
b = [1, "Hello", 1/4, True]

 

 

그러면 삼성전자의 1월부터 12월까지의 종가를 튜플, 리스트로 만들어 좀 더 살펴보겠습니다.

samsung_closes_tuple = (40000, 45000, 50000, 55000, 60000, 60500, 61000, 67000, 76000, 80000, 82000, 83000)
samsung_closes_list = [40000, 45000, 50000, 55000, 60000, 60500, 61000, 67000, 76000, 80000, 82000, 83000]

 

 

이렇게 튜플과 리스트를 만들어 데이터에 접근하는 방법은 다음과 같습니다.

튜플[접근할 데이터의 순서]
리스트[접근할 데이터의 순서]

 

 

데이터의 순서라고 하면 문자의 슬라이싱에서 설명드린 것처럼 0부터 카운팅이 되며 

이 ‘접근할 데이터의 순서’를 앞으로 인덱스(index)라고 불러 사용하겠습니다.

예를 들어 첫번째 값인 40000에 접근하려면 0번째 인덱스에 접근하면 됩니다.

samsung_closes_tuple[0]  # 40000
samsung_closes_list[0]  # 40000

 

 

이 인덱스가 실제 튜플, 리스트가 담고 있는 데이터의 길이보다 크면 안됩니다.

12개의 데이터를 담고 있고 0번째부터 카운팅이 되니 최대 인덱스는 11까지입니다.

그러면 가지고 있는 데이터 길이보다 큰 인덱스에 접근하면 어떻게 될까요?

 

한번 12번째 인덱스에 접근해보겠습니다.

samsung_closes_tuple[12]  # IndexError: tuple index out of range
samsung_closes_list[12]

 

 

튜플의 범위(range)를 벗어나는 인덱스에 접근했다는 Index Error가 발생하며 종료됩니다.

(samsung_closes_llist[12]가 먼저 실행됐다면 똑같이 리스트의 범위를 벗어 났다는 에러가 나며 종료됩니다.)

 

리스트의 범위란 리스트가 가지고 있는 데이터의 양(길이)를 의미하며 이를 알아내는 방법은 내장함수인 len()을 이용하는 것입니다. len()에 괄호 사이에 튜플, 리스트를 전달하면 됩니다.  

print(len(samsung_closes_tuple))  # 12
print(len(samsung_closes_list))   # 12 

 

 

그러면 이렇게 생김새나 쓰임새나 비슷한 튜플과 리스트는 무슨 차이가 있을까요?

먼저 데이터를 묶어 놨다고 해도 여기서 수정이나 삽입(신규), 삭제가 있을 수 있습니다.

하지만 튜플은 이 삽입,삭제, 수정이 불가한 반면 리스트는 가능합니다.

 

예를 들어 우리가 마지막 데이터인 83000에 접근해보겠습니다. 11번째 데이터니 인덱스 11를 이용하겠습니다.

samsung_closes_tuple[11]  # 83000
samsung_closes_list[11]   # 83000 

 

하지만 이 역시 데이터를 저장할 수 있는 변수이기에 변수에 값을 할당하듯이 값을 변경할 수 있습니다.

samsung_closes_tuple[11] = 100000  # 튜플은 수정 불가 실행하면 에러 발생!
samsung_closes_list[11] = 100000   # 83000 > 10000으로 변경됨



여기서 튜플은 한번 선언한 값의 변경이 불가하며 위 코드를 그대로 수행하면 다음과 같은 에러가 발생합니다.

'tuple' object does not support item assignment

 

 

그러면 이렇게 수정도 안되고 삽입, 삭제도 안된다는 튜플은 어디에 쓸까요?

리스트만 있으면 되지 않나요? 하실 수도 있습니다.

 

하지만 값이 변경될 수 있다는 것이 꼭 장점은 아니며 프로그램이 실행되는 동안 변경되지 말아야 할 값들이 있을 수 있습니다.

예를 들어 1월부터 12월을 담은 변수를 만들어 달력처럼 사용한다고 하면 이 값들은 변경될 필요없이 계속 사용됩니다. 이렇게 변경되지 말아야 할 값들을 넣을 때 튜플의 사용이 필요할 수 있습니다.

months_eng = ('January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December')

 

 

그러면 튜플에 대해서는 여기까지 설명드리고 앞으로 중점적으로 사용할 리스트에 대해서 알아보도록 하겠습니다.

리스트는 데이터의 삽입, 삭제가 가능하다고 말씀 드렸습니다.

새로운 데이터를 삽입하고 싶을 때는 다음과 같이 사용합니다.

리스트.append(값)



그러면 다음과 같이 1,2,3을 담고 있는 a라는 리스트에 4라는 값을 넣어보도록 하겠습니다. 

a = [1, 2, 3]
a.append(4)

 

append라는 내장함수를 사용하면 리스트의 맨 마지막 자리에 넣고자 하는 데이터를 넣어주며 len()을 통해 append 전에 리스트 길이와 후의 리스트 길이를 통해서 삽입이 이루어졌음을 알 수 있습니다. 

a = [1, 2, 3]

len(a)  # 3 
a.append(4)
len(a)  # 4 

 

 

여기서 지금까지 종종 사용해왔던 len()이나 append() 같은 함수들은 Python에 내장된 기능이며 이런 함수들은 양이 많기 때문에 잠깐은 답답하시더라도 천천히 익숙해지실테니 걱정하지 않으셔도 좋을 것 같습니다.

참고로 append의 사용은 리스트 변수 다음에 점(.)을 찍고 사용해야 하며 리스트 타입이 아닌 변수이거나 점(.)을 빼먹으면 에러가 발생합니다. 

var = 1
var.append(1)

# AttributeError: 'int' object has no attribute 'append'



왜 에러가 발생하냐면 append라는 내장 함수는 리스트 타입의 데이터만 사용할 수 있도록 미리 만들어져 있기 때문에 그렇습니다.

다음은 데이터를 수정하는 방법에 대해서 알아보겠습니다.

리스트[수정할 인덱스] = 새로운 값

 

 

수정하고 싶은 인덱스에 접근해서 수정하고자 하는 새로운 값을 할당하면 바로 수정이 됩니다. 하지만 주의해야할 점은 리스트의 범위를 벗어나는 인덱스, 즉 없는 인덱스에 접근하려는 경우 에러가 발생합니다.

a = [1, 2, 3]

a[0] = 3 

# a > [3, 2, 3]

 

다음은 데이터를 삭제하는 방법에 대해서 알아 보겠습니다.

del 리스트[삭제할 인덱스]

 

 

삽입할 때 사용한 코드를 가지고 예를 들어보겠습니다.

삭제할 인덱스란 마찬가지로 0부터 카운팅 되는 값 중 삭제하고 싶은 번호입니다. 

a = [1, 2, 3, 4]

 

여기서 3은 인덱스 2이기 때문에 3 값을 지우고자 한다면 다음 코드를 만들어야 합니다. 

del a[2]

 

그럼 삭제 후에 리스트 a를 살펴 보겠습니다. 

a = [1, 2, 3, 4]
del a[2]
print(a)  # [1, 2, 4]

 

먼저 리스트가 가지고 있는 모든 값을 출력하기 위해서는 print(리스트변수)를 이용합니다.

del a[2]를 수행하기 전에는 1,2,3,4를 가지고 있던 리스트 a에 삭제 후에는 [1, 2, 4]만 남게 되었습니다.

 

그러면 마지막으로 패킹(packing)과 언패킹(unpacking)에 대해서 알아보겠습니다. 

리스트를 선언하는 방법은 다음처럼 데이터를 ‘,’로 연결하고 앞뒤로 대괄호([, ])를 사용했습니다. 

a = [1, "Hello", 1/4, True]

 

 

이렇게 1, "Hello", 1/4, True라는 4개의 서로 다른 타입의 데이터를 a라는 하나의 변수에 저장하는 방식을 싸맨다고 해서 패킹(Packing)이라고 합니다.

 

그러면 반대로 a에 저장한 값들을 풀어낼 때는 언패킹(Unpacking)이라고 하며 다음처럼 사용합니다.

변수, 변수, 변수, 변수 = 리스트 

 

왼쪽에는 리스트에 들어 있는 데이터의 수만큼에 해당하는 변수가 와야 합니다.

예를 들면 다음과 같은 코드는 에러가 납니다.

a = [1, "Hello", 1/4, True]

b, c, d = a

#  ValueError: too many values to unpack (expected 3)

 

 

a가 갖고 있는 데이터는 4개인데 b, c, d 3개의 변수를 이용해 데이터를 언패킹하려고 하니 에러가 발생하는 것입니다.

제대로 언패킹하고자 한다면 다음처럼 언패킹할 대상의 데이터 수와 이를 저장할 변수의 수가 동일해야 합니다.

a = [1, "Hello", 1/4, True]

b, c, d, e = a
print(b, c, d, e)
# a = 1, b = Hello, c = 0.25, d = True

 

언패킹이 성공하면 사용한 b, c, d, e 순서대로 리스트 a에 들어있는 값들을 그대로 꺼내올 수 있습니다.

 

지금까지 튜플 및 리스트에 대해서 알아보았습니다. 

특히 리스트는 사용법뿐만 아니라 패킹, 언패킹에 대해서도 알아보았지만 패킹, 언패킹은 튜플도 가능하다는 점을 간단히 기억해주시기 바랍니다. 

 

리스트는  좀 더 집중해서 배웠지만 데이터를 리스트에 삽입하는 다른 방법들도 존재하기도 하고 리스트에 대해 다 설명 드렸다고 할 수 없습니다. 그래서 혹시 앞으로 리스트 사용에서 모르는 부분이 나온다고 해도 ‘배워야 할 것이 너무 많다.. 어렵다’라고 생각하기 보다 트레이딩 시스템 개발이라는 우선적 목표를 이뤄내기 위해 필요한 부분부터 배우다보니 일어나는 당연한 현상이라고 생각하시기 바라겠습니다. 고생하셨습니다.

 

 


같이 보시면 좋을 글

2021/02/10 - [파이썬/주식 자동매매] - 주식매매프로그램 개발 노하우, 소스를 담은 전자책이 발간되었습니다.

 

주식매매프로그램 개발 노하우, 소스를 담은 전자책이 발간되었습니다.

주식매매프로그램 개발 노하우에 관한 제 전자책이 발간되었습니다. https://kmong.com/gig/292764 주식매매프로그램, 쉽게 따라 만드는 노하우와 소스를 드립니다. | 36000원부터 시작 가능한 총 평 0개

jsp-dev.tistory.com

 

2021/01/24 - [파이썬/주식 자동매매] - Python 키움API 자동매매프로그램 개발-9.Python 기초편 딕셔너리 사용

 

 

 

반응형
이 포스팅은 쿠팡파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.

댓글