lists v. tuples, recap:
what do they have in common: * heterogeneous sequences of data * can
be iterated over with for
loop * can be concatenated with
+
(but we rarely concatenate lists!) * subscripting (e.g.,
stuff[i]
) offers random access * both offer
slicing (which is a Python specialty)
tuples are immutable
lists are mutable:
a[i] = ... <--- legal for lists, NOT for tuples
.append
.pop
there is nothing you can compute with lists that you cannot already compute with tuples
however, some things are way faster with lists
a.append(...)
is (generally) much faster than t +=
(...,)
x = a.pop()
is like (and also faster than):
x = t[-1]
t = t[:-1]
general mutability:
a[i] = x # replace whatever was at position i with value x
consider:
from random import randrange
from time import perf_counter_ns
# simplified (even slower!) bubble sort
def bubble_sort(a):
for _ in range(len(a)):
for i in range(1, len(a)):
if a[i-1] > a[i]:
swap(a, i-1, i)
def swap(a, i, j):
t = a[i]
a[i] = a[j]
a[j] = t
def tuple_bubble(t):
u = t
for _ in range(len(t)):
for i in range(1, len(t)):
if u[i-1] > u[i]:
u = tuple_swap(u, i-1, i)
return u
def tuple_swap(t, i, j):
u = tuple_replace(t, i, t[j])
u = tuple_replace(u, j, t[i])
return u
# return version of t with position i replaced with x
def tuple_replace(t, i, x):
u = t[:i] + (x,) + t[i+1:]
return u
def random_tuple(n):
t = ()
for _ in range(n):
t += (randrange(n),)
return t
def random_list(n):
a = []
for _ in range(n):
a.append(randrange(n))
return a
def time_it(f, x):
t0 = perf_counter_ns()
y = f(x)
d = perf_counter_ns() - t0
return (y, d)
# now compare:
>>> big_tuple = random_tuple(10**6)
>>> big_list = list(big_tuple)
>>> time_it(bubble_sort, big_list)
>>> time_it(tuple_bubble, big_tuple)