일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
- leetcode 풀기
- binary search
- 잇츠디모
- 릿코드
- 파이썬알고리즘풀기
- 파이썬알고리즘
- python xor
- LeetCode
- 상가수익률계산기
- 코틀린기초
- 파이썬릿코드
- 파이썬 릿코드
- python priority queue
- python Leetcode
- 파이썬릿코드풀기
- leetcode풀이
- 파이썬 알고리즘
- python sorted
- 알고리즘풀기
- 알고리즘풀이
- python 알고리즘
- 릿코드 풀기
- leetcode풀기
- python zip_longest
- 릿코드 파이썬
- 릿코드풀이
- 파이썬 프로그래머스
- 파이썬 알고리즘 풀기
- python 릿코드
- 릿코드풀기
- Today
- Total
소프트웨어에 대한 모든 것
[파이썬] tuple 파헤치기 본문
파이썬에서 튜플은 리스트와 비슷합니다.
가장 큰 차이점은 튜플은 요소를 변경할 수 없습니다.
즉, 튜플은 immutable 특징을 갖습니다.
튜플 생성
튜플은 소괄호 () 를 통해서 생성할 수 있습니다.
여러 가지 데이터 타입을 함께 저장 가능합니다.
# 비어있는 튜플 생성
a = ()
print(a)
# int 요소를 갖는 튜플 생성
b = (1, 2, 3)
print(b)
# mixed datatypes를 갖는 튜플 생성
c = (1, 'hello world', 3.3)
print(c)
# nested 튜플 생성
d = (1, 'hello', [2, 3], (4, 5))
print(d)
출력
()
(1, 2, 3)
(1, 'hello world', 3.3)
(1, 'hello', [2, 3], (4, 5))
소괄호 없이도 튜플은 생성 가능합니다.
# () 없이 튜플 생성
a = 1, 2, 3, 'hello'
print(a)
print(type(a))
# 튜플 언패킹
n1, n2, n3, s = a
print(n1, n2, n3, s)
출력
(1, 2, 3, 'hello')
<class 'tuple'>
1 2 3 hello
하나의 요소로 튜플을 만들 수 없습니다.
하나의 요소로 튜플을 만들 때는 마지막에 콤마를 꼭 입력해야 합니다.
# a는 튜플이 아님
a = ('hello')
print(type(a))
# 마지막에 comma를 지정 했으므로 a는 튜플
a = ('hello',)
print(type(a))
# 소괄호가 없더라도 a는 튜플
a = 'hello',
print(type(a))
출력
<class 'str'>
<class 'tuple'>
<class 'tuple'>
튜플 인덱싱
index operator []를 통해서 튜플 아이템에 접근 가능합니다.
index 시작은 당연히 0부터 입니다.
# 첫 번째 아이템, 마지막 아이템에 접근
a = ['w', 'o', 'r', 'l', 'd']
print(a[0])
print(a[4])
# nested tuple
a = ['w', 'o', ['d', 'o', 'g'], 'l', 'd']
print(a[2][0])
print(a[2][1])
print(a[2][2])
출력
w
d
d
o
g
리스트와 마찬가지로 negative 인덱싱도 가능합니다.
# Negative Indexing
a = ['w', 'o', 'r', 'l', 'd']
print(a[-1])
print(a[-2])
print(a[-5])
출력
d
l
w
튜플 슬라이싱
slicing operator 콜론(:)을 사용해서 튜플 아이템의 range에 접근 가능합니다.
a = ('w', 'e', 'l', 'l', 's', 'w')
# a[1], a[2]
print(a[1:3])
# 첫번째 인덱스부터 마지막에서 두 번째 전까지
print(a[:-2])
# 3번째 인덱스부터 끝까지
print(a[3:])
# 전체 아이템
print(a[:])
# 전체 아이템을 반대로
print(a[::-1])
출력
('e', 'l')
('w', 'e', 'l', 'l')
('l', 's', 'w')
('w', 'e', 'l', 'l', 's', 'w')
('w', 's', 'l', 'l', 'e', 'w')
튜플 변경 (수정)
리스트와 다른 튜플의 가장 큰 특징은 immutable 입니다.
즉, 한 번 할당된(assigned)된 튜플의 값은 변경할 수 없다는 얘기입니다.
a = ('w', 'e', 'l', 'l', 's', 'w')
# 튜플의 0 index의 값을 변경 -> TypeError 발생
a[0] = 'z'
결과
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_28388/3265170153.py in <module>
2
3 print(a[0])
----> 4 a[0] = 'z'
TypeError: 'tuple' object does not support item assignment
그렇지만, 튜플 내의 nested item이 mutable의 경우에는 변경 가능합니다.
a = ('w', 'e', 'l', 'l', ['h', 'e', 'l', 'l', 'o'], 'w')
# 4번째 인덱스의 리스트 Data Type의 0번째 인덱스의 아이템을 h->q로 변경
# a[4]는 mutable 리스트이기 때문에 가능함
a[4][0] = 'q'
print(a)
출력
('w', 'e', 'l', 'l', ['q', 'e', 'l', 'l', 'o'], 'w')
+ 연산자를 통해서 튜플을 concatenation 할 수 있으며, * 연산자를 통해서 주어진 수만큼 n times 반복된 튜플을 생성할 수 있습니다.
# Concatenation
a = (1, 2, 3)
b = (4, 5, 6)
c = a + b
print(c)
# Repeat
print(a * 3)
출력
(1, 2, 3, 4, 5, 6)
(1, 2, 3, 1, 2, 3, 1, 2, 3)
튜플 삭제
튜플 내의 아이템을 삭제 가능할까요?
튜플은 immutable 속성을 가지기 때문에 튜플 내의 아이템을 변경할 수 없기 때문에 튜플 내의 아이템을 삭제할 수 없습니다. 단 del 키워드를 통해서 튜플 전체 삭제는 가능합니다.
a = ('w', 'e', 'l', 'l', 's', 'w')
# 삭제 불가능
# TypeError 에러 발생
# del a[0]
# 튜플 전체 삭제 가능
del a
# NameError 발생
# 튜플 a가 삭제 되었기 때문에 a는 정의되지 않는 것임
print(a)
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_28388/1405388446.py in <module>
10 # NameError 발생
11 # 튜플 a가 삭제 되었기 때문에 a는 정의되지 않는 것임
---> 12 print(a)
NameError: name 'a' is not defined
튜플 메소드(함수)
튜플에서는 아이템을 추가, 삭제하는 함수는 지원하지 않습니다.
count(), index() 함수 두 개만 지원합니다.
a = ('w', 'e', 'l', 'l', 's', 'w')
# 'l'의 갯 수
print(a.count('l'))
# 's'가 위치한 인덱스
print(a.index('s'))
출력
2
4
튜플 membership and iterating
리스트와 같이 in 키워드를 사용해서 아이템이 튜플에 있는지 체크할 수 있습니다.
a = ('w', 'e', 'l', 'l', 's', 'w')
# In operation
print('e' in a)
print('s' in a)
# Not in operation
print('q' in a)
출력
True
True
False
반복문을 통해서 tuple 아이템을 반복 접근할 수 있습니다.
for name in ('james', 'steve'):
print(name)
james
steve
튜플을 dict의 키로 사용
튜플은 dictionary의 key로 사용 가능합니다. 이는 튜플의 immutable 속성 때문에 가능한 것으로 보입니다. 아이템이 할당 후 값이 추가/수정/삭제가 불가능하기 때문에 hashing된 값을 만들 수 있어서 고유한 key 값을 생성할 수 있기 때문입니다. 리스트는 key로 사용 불가능합니다.
d = {}
tuple_items = (1, 2, 3)
list_items = [4, 5, 6]
# 튜플을 dictionary의 키로 지정 가능
d[tuple_items] = 'a'
print(d)
# 리스트를 dictionary의 키로 지정하면 에러 발생
# 에러 발생 -> Tunhashable type: 'list'
d[list_items] = 'b'
print(d)
출력
{(1, 2, 3): 'a'}
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_28388/4038970714.py in <module>
10 # 리스트를 dictionary의 키로 지정하면 에러 발생
11 # 에러 발생 -> Tunhashable type: 'list'
---> 12 d[list_items] = 'b'
13 print(d)
TypeError: unhashable type: 'list'
튜플에 nested 아이템으로 리스트로 추가하면 dictionary의 key로 사용 가능할까요?
튜플 내에 mutable한 리스트 data type이 들어갔기 때문에 고유한 hasing을 만들 수 없기 때문에 dictionary의 key로 사용할 수 없습니다.
d = {}
# nested tuple
tuple_items = (1, ['a', 'b'], 3)
# 에러 발생 -> TypeError: unhashable type: 'list'
d[tuple_items] = 'q'
출력
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_28388/982697642.py in <module>
2
3 tuple_items = (1, ['a', 'b'], 3)
----> 4 d[tuple_items] = 'q'
TypeError: unhashable type: 'list'
튜플 vs 리스트 메모리 사용량
튜플은 fixed_-size, 리스트는 variable-sized입니다. 튜플은 구조체 내에 elements를 directly 하게 저장하고, 리스트는 indirect 하게 pointer로 저장합니다. 이런 차이 때문에도 튜플이 리스트보다 빠릅니다.
그리고 리스트는 메모리 할당 시 over-allocate 합니다. 리스트는 append()를 지원하는데 over-allocate로 메모리를 할당하지 않으면 항상 O(n)의 시간 복잡도를 갖게 됩니다. append()에 대한 비용을 O(1)으로 맞추기 위해서는 over-allocate로 메모리 할당이 필요합니다.
/* This over-allocates proportional to the list size, making room
* for additional growth. The over-allocation is mild, but is
* enough to give linear-time amortized behavior over a long
* sequence of appends() in the presence of a poorly-performing
* system realloc().
* The growth pattern is: 0, 4, 8, 16, 25, 35, 46, 58, 72, 88, ...
* Note: new_allocated won't overflow because the largest possible value
* is PY_SSIZE_T_MAX * (9 / 8) + 6 which always fits in a size_t.
*/
이러한 이유로 동일한 아이템 저장 시 튜플은 리스트보다 메모리 사용량이 적습니다.
import sys
# as tuple
a = (1, 2, 3)
print(sys.getsizeof(a))
b = [1, 2, 3]
print(sys.getsizeof(b))
출력
32
60
튜플의 장점 (리스트 보다)
튜플은 리스트와 거의 유사합니다.
리스트보다 튜플을 사용할 때 뭐가 장점이 될까요?
- 일반적으로 튜플은 heterogeneous (다른) 데이터 타입을 저장할 때, 리스트는 homogeneous (유사) 데이터 타입을 저장할 때 사용
- 튜플은 immutable이기 때문에 iterating 시 리스트보다 (약간) 빠름
- 튜플은 immutable 아이템들을 갖기 때문에 dictionary의 키로 사용 가능
- 변경되지 않는 데이터를 튜플로 사용하면 write-protected를 보장
함께 보면 좋은 글
https://www.programiz.com/python-programming/tuple
Python Tuple (With Examples)
Python Tuple In this article, you'll learn everything about Python tuples. More specifically, what are tuples, how to create them, when to use them and various methods you should be familiar with. Video: Python Lists and Tuples A tuple in Python is similar
www.programiz.com
https://www.tutorialspoint.com/python/python_tuples.htm
Python - Tuples
Python - Tuples A tuple is a collection of objects which ordered and immutable. Tuples are sequences, just like lists. The differences between tuples and lists are, the tuples cannot be changed unlike lists and tuples use parentheses, whereas lists use squ
www.tutorialspoint.com
https://www.codesansar.com/python-programming/which-one-faster-access-list-or-tuple-and-why.htm
Which one is faster to access list or a tuple and why?
Which one is faster to access list or a tuple and why?
www.codesansar.com
https://stackoverflow.com/questions/46664007/why-do-tuples-take-less-space-in-memory-than-lists
Why do tuples take less space in memory than lists?
A tuple takes less memory space in Python: >>> a = (1,2,3) >>> a.__sizeof__() 48 whereas lists takes more memory space: >>> b = [1,2,3] >>> b.__sizeof__() 64 ...
stackoverflow.com