The difference betwen Lists and Tuples in Python

Page content

강의 홍보

I. 개요

  • 이번 시간부터 본격적으로 파이썬의 기초 자료형에 대해 간단한 튜토리얼을 준비했다.
  • 데이터 분석과는 큰 관계가 없을 수 있지만, 데이터 정제 할 때, 도움이 되기도 한다.
  • 그 중에서 면접의 단골질문과 같은 Lists & Tuple에 대해 나누는 시간을 가졌다.

II. Lists

  • 먼저 Lists[] 형태로 정의가 된다.
alphabet = ['A', 'B', 'C', 'D']
print(alphabet)
['A', 'B', 'C', 'D']
  • 코드는 간단하다. 그러나 함의하고 있는 내용은 다음과 같다.
    • List는 정렬(ordered)되었다.
    • List는 다양한 형태의 데이터 유형을 담을 수 있다.
    • List안에 있는 값은 인덱스로 접근한다.
    • List안에 또다른 List를 담을 수 있다.
    • List는 변하기 쉽다.
    • List는 동적이다.

(1) List는 정렬(ordered)되었다.

  • 우선 코드로 확인하자.
a1 = [1, 2, 3, 4]
a2 = [2, 3, 4, 1]

a1 == a2
False
a1 is a2
False
[1, 2, 3, 4] == [2, 3, 4, 1]
False
  • 일련의 코드는 a1a2가 같지 않다는 것을 프로그래밍적으로 증명한 것이다.
    • 좀 더 쉽게 표현하면 List안에 있는 값은 순서가 있다는 뜻이다.

(2) List는 다양한 형태의 데이터 유형을 담을 수 있다.

  • List의 편리성이기도 하지만, 분석시에는 데이터프레임으로 변환할 때 큰 애로사항이 되기도 한다.
  • 우선, 코드로 확인해보자.
multi_values = [11.1, 'foo', 3, 5, 'bar', True, False, 3.1245]
print(multi_values)
[11.1, 'foo', 3, 5, 'bar', True, False, 3.1245]
  • 또한, List는 다양한 함수, class, 심지어는 모듈도 담을 수 있다.
float
float
len
<function len>
def temp():
  pass
temp
<function __main__.temp>
import math
math
<module 'math' (built-in)>
multi_objects = [float, len, temp, math]
multi_objects
[float, <function len>, <function __main__.temp>, <module 'math' (built-in)>]

(3) List안에 있는 값은 인덱스로 접근한다.

  • 다음 그림이 인덱스로 접근하는 기본적인 방법이다.
    • 참고로 또다른 분석 언어인 R0이 아닌 1부터 시작한다.
  • 소스코드로 빠르게 확인해보자.
temp = ["A", "B", "C", "D", "E"]
temp[0]
'A'
temp[1]
'B'
temp[4]
'E'
  • 그런데, Negative List 형태로도 접근할 수 있다.
    • -1, -2와 같은 형태로 접근하는 것이다.
  • 코드를 통해 확인해보자.
temp[-1]
'E'
temp[-4]
'B'
temp[-5]
'A'
  • 슬라이싱을 활용한 인덱스 접근법도 있다.
    • temp[m:n] 형태로 From M to N으로 접근한다.
  • 코드를 통해서 확인해보자.
temp[0:5]
['A', 'B', 'C', 'D', 'E']
temp[2:4]
['C', 'D']
temp[-5:-1]
['A', 'B', 'C', 'D']
temp[-5:]
['A', 'B', 'C', 'D', 'E']
  • 이 외에도, 슬라이싱 기법을 활용한 다양한 접근법이 있다. 스택오버플로우의 문서를 확인해보면 보다 더 많은 정보를 얻을 수 있다.

(4) List안에 또다른 List를 담을 수 있다.

  • List안에 다양한 객체가 들어가 있음을 확인했다.
  • 그런데, List안에 또 다른 List가 들어갈 수도 있다.

  • 코드를 통해 확인해보자.
x = ['a', ['bb', ['ccc', 'ddd'], 'ee', 'ff'], 'g', ['hh', 'ii'], 'j']
x
['a', ['bb', ['ccc', 'ddd'], 'ee', 'ff'], 'g', ['hh', 'ii'], 'j']
  • 인덱스로 접근하는 방법에 대해 배웠기 때문에, 하나씩 접근해보도록 한다.
  • 우선 a에 접근해보자.
x[0]
'a'
  • 이번에는 bb에 접근해보자.
x[1]
['bb', ['ccc', 'ddd'], 'ee', 'ff']
  • x[1] 안에 또다른 리스트가 있음을 확인했다.
    • bb에 접근하려면 x[1]에서 []를 추가해서 접근하면 된다.
x[1][0]
'bb'
  • 이번에는 ccc에 접근해보자.
x[1][1][0]
'ccc'
  • 위와 같은 방식으로 Nested List의 값에 대해 보다 쉽게 접근하는 방법을 배울 수 있었다.

(5) List는 변하기 쉽다.

  • 보통 Mutable이라고 문법적으로 표현을 많이 한다.
  • 우선 코드로 이해해보자.
message = "strings immutable"
message[0]
's'
  • s 대신에 p를 입력하도록 해보자. 이론적으로는 `message[0] = p’를 하면 된다.
message[0] = 'p'
print(message)
---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

<ipython-input-84-0ddf8fde634f> in <module>()
----> 1 message[0] = 'p'


TypeError: 'str' object does not support item assignment
  • 에러가 났다. 즉, 문자열은 바로 치환이 되지 않는다. 이러한 것을 문법적으로 Immutable이라고 한다.
  • 그러면 List는 어떨까?
a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']
a[1]
'bar'
  • bar 대신에 이제 숫자 10을 대입해보자.
a[1]=10
a
['foo', 10, 'baz', 'qux', 'quux', 'corge']
  • string에서 바뀌지 않는 것이 list에서 쉽게 바뀐 것을 확인할 수 있다.
  • 이렇게 바뀌는 것을 Mutable이라고 표현한다.
    • 반대로 TupleImmutable이라고 표현한다. (추후에 조금 더 깊게 다루도록 한다)

(6) List는 동적이다.

  • 사실 Mutable이라는 뜻 자체가 매우 동적임을 나타난다.
  • 필자는 보통 자유도가 높다라고 표현하고 싶다.
  • 다양한 형태로 작업이 가능하다.
  • 우선 다양한 값을 Add추가 하는 것을 진행하자.
temp = ['A', 'B', 'C', 'D', 'E', 'F']
temp[3:3] = [1, 2, 3]
temp
['A', 'B', 'C', 1, 2, 3, 'D', 'E', 'F']
temp += [1000]
temp
['A', 'B', 'C', 1, 2, 3, 'D', 'E', 'F', 1000]
  • 이번에는 반대로 삭제하는 것을 진행해보자.
temp[3:6] = []
temp
['A', 'B', 'C', 'D', 'E', 'F', 1000]
del temp[6]
temp
['A', 'B', 'C', 'D', 'E', 'F']

III. Tuple

  • 리스트와 비슷하지만 조금 다른 Tuple에 대해 소개한다.
  • 문법적 특징은 ()라고 표현한다.
  • 그리고, TupleImmutable이다.
temp = ('A', 'B', 'C', 'D', 'E', 'F')
temp
('A', 'B', 'C', 'D', 'E', 'F')
  • List와 매우 유사하기 때문에 List에 있는 문법들을 하나씩 응용해보는 것을 권한다.
  • Immutable인지 확인해보자.
  • C 대신에 Cat을 대입해보자.
temp[2] = "Cat"
---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

<ipython-input-97-d6cba27b526a> in <module>()
----> 1 temp[2] = "Cat"


TypeError: 'tuple' object does not support item assignment
  • string에서 봤던 동일한 에러가 나온 것을 확인할 수 있다.

(1) 왜 Tuple을 사용할까?

  • 프로그래밍적으로 TupleList보다 연산속도가 빠르다.
    • 굳이 증명할 필요는 없다. 개념적으로 이해만 하자.
  • 데이터 분석적으로 접근하면, 특정 데이터가 변하지 않도록 방지하는 기법으로 Tuple을 사용할 수 있다.
  • 또다른 데이터 구조로써 Dictionary를 배울텐데, 이 때 Dictionary도 문자열과 같은 immutable type을 요구한다.
  • Tuple의 강력함은 Packing & Unpacking의 기법이다.
    • Tuple을 일종의 여행용 가방으로 생각하면 이해하기가 보다 쉽다.

t = ('foo', 'bar', 'baz', 'qux')
t
('foo', 'bar', 'baz', 'qux')
  • 이 때, 각각의 element들을 다른 이름으로 저장해보자.
    • 기존에는 t[0]과 같은 형태로 호출했다면, 이번에는 별도로 저장해보자는 뜻이다.
  • 이를 Unpacking이라고 부른다.

(s1, s2, s3, s4) = t 
s1
'foo'
s2
'bar'
s3
'baz'
s4
'qux'
  • 이 때, 반드시 좌우의 값이 동일하게 작동해야 한다.
  • 만약, 좌우의 값이 일치하지 않으면 에러가 발생한다.
  • 코드를 통해 확인해보자.
(a1, a2, a3) = t
---------------------------------------------------------------------------

ValueError                                Traceback (most recent call last)

<ipython-input-104-76bce831b49d> in <module>()
----> 1 (a1, a2, a3) = t


ValueError: too many values to unpack (expected 3)

(2) swap

  • 스왑은 보통 맞바꾸다의 뜻을 가지고 있다.
  • Tuple에서는 매우 쉽게 swap이 가능하다.
a1 = "chloe"
v1 = "loves"
a2 = "evan"

temp = a1, v1, a2 # Tuple 형태로 표시됨
temp
('chloe', 'loves', 'evan')
  • 여기에서 chloeevan의 위치를 바꾼다.
a1, a2 = a2, a1
temp = a1, v1, a2 # Tuple 형태로 표시됨
temp
('evan', 'loves','chloe')
  • 이렇게 매우 쉽게 바뀌는 것을 확인할 수 있다.

VI. 결론

  • 지금까지 listtuple에 대해 배웠다.
  • 그 중에서 가장 중요한 개념은 MutableImmutable의 차이다.
  • 다음 시간에는 Dictionary에 대해 배우도록 한다.

V. Reference

Sturtz, J. (2018, September 26). Lists and Tuples in Python. Retrieved June 17, 2020, from https://realpython.com/python-lists-tuples/