# Literal syntax (parentheses are optional but recommended)
coords = (10, 20)
single = (42,) # ⚠️ Comma is REQUIRED for single element!
not_tuple = (42) # This is just an int in parentheses
empty = ()
# From other iterables
from_list = tuple([1, 2, 3]) # (1, 2, 3)
from_str = tuple('Python') # ('P', 'y', 't', 'h', 'o', 'n')t = (10, 20, 30, 20, 40)
# Indexing & Slicing (same as lists)
print(t[0]) # 10
print(t[-1]) # 40
print(t[1:3]) # (20, 30)
# Membership
print(20 in t) # True
# Count & Index
print(t.count(20)) # 2
print(t.index(30)) # 2
# Concatenation & Repetition (creates NEW tuples)
new_t = t + (50, 60)
rep_t = (0,) * 3 # (0, 0, 0)t = (1, 2, [3, 4])
# t[0] = 99 # TypeError! 'tuple' object does not support item assignment
# ⚠️ BUT if a tuple contains a MUTABLE object, that inner object CAN change!
t[2][0] = 99
print(t) # (1, 2, [99, 4]) — Tuple still points to the same list object# Basic unpacking
x, y, z = (10, 20, 30)
# Swap variables (Pythonic!)
a, b = 10, 20
a, b = b, a # a=20, b=10
# Extended unpacking (* operator)
first, *rest = (1, 2, 3, 4, 5)
print(first) # 1
print(rest) # [2, 3, 4, 5] (becomes a list!)
*middle, last = (1, 2, 3, 4, 5)
first, *middle, last = (1, 2, 3, 4, 5)
# Nested unpacking
(a, b), (c, d) = (1, 2), (3, 4)# 1. Dictionary keys (must be hashable/immutable)
locations = {
(35.68, 139.69): 'Tokyo',
(40.71, -74.00): 'New York'
}
# 2. Function return values (multiple returns are actually tuples)
def min_max(lst):
return min(lst), max(lst)
result = min_max([3, 1, 4, 1, 5])
print(type(result)) # <class 'tuple'>
# 3. Slight performance & memory advantage over lists
import sys
print(sys.getsizeof([1,2,3])) # 88 bytes
print(sys.getsizeof((1,2,3))) # 72 bytesCreate a function `swap_values(a, b)` that returns the swapped values as a tuple. Create a function `get_stats(numbers)` that takes a list and returns a tuple of `(min, max, sum, average)`. Use tuple unpacking to extract and print the results. Finally, demonstrate that a tuple can be a dict key by creating a coordinate mapping.