ᚱᛗ
© 2022
Powered by Hugo

Slicing and Striding Lists

Table of Contents

Slicing

Two things to note:

  • Python is zero-based indexed. Eg. a list with 5 elements, will be indexed from 0 to 4.
  • Intervals are closed from the left and open from the right.

Entire list

l = list(range(15))
print(l)
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
assert l == l[:] == l[0 : len(l)]

First n

n = 5
print(f"First {n} elements:", l[:n])
# First 5 elements: [0, 1, 2, 3, 4]

Last n

n = 5
print(f"Last {n} elements:", l[-n:])
# Last 5 elements: [10, 11, 12, 13, 14]

From element i to element j

i, j = 5, 10
print(f"From index {i} to {j}:", l[i:j])
# From index 5 to 10: [5, 6, 7, 8, 9]

From n, excluding last m

n = m = 5
print(f"From {n} and exclude last {m}:", l[n:-m])
# From 5 and exclude last 5: [5, 6, 7, 8, 9]

Last n, excluding last m

n, m = 5, 3
print(f"Last {n} excluding last {m}:", l[-n:-m])
# Last 5 excluding last 3: [10, 11]

Overwriting a smaller slice with a larger list

a = [1, 2, 3, 4, 5]
print(a[2:4])  # [3, 4]
a[2:4] = ["nul", "ett", "to", "tre", "fire", "fem"]
print(a)
# [1, 2, 'nul', 'ett', 'to', 'tre', 'fire', 'fem', 5]

Overwriting a larger slice with a smaller list

a = [1, 2, 3, 4, 5]
print(a[1:-1])  # [2, 3, 4]
a[1:-1] = ["null"]
print(a)
# [1, 'null', 5]

Copy contents (diff memory address). Changes in A/B don’t change B/A

A = ["u", "w", "x", "y", "z"]
B = A[:]  # assign the contents of A to a new object B
assert B == A and B is not A
B = B[:2]  # a new memory address for B is created
# B after re-assigning B
print(B)  # ['u', 'w']
# A after re-assigning B
print(A)  # ['u', 'w', 'x', 'y', 'z']
assert B != A

Copy objects (diff memory address). Changes in A/B don’t change B/A

A = ["u", "w", "x", "y", "z"]
B = A  # create a copy of object A. shared memory address
assert A is B
assert hex(id(A)) == hex(id(B))  # same location in memory
A = A[:2]  # a new memory address for A is created
assert hex(id(A)) != hex(id(B))
# A after re-assigning A
print(A)  # ['u', 'w']
# B after re-assgining A
print(B)  # ['u', 'w', 'x', 'y', 'z']
assert B is not A and B != A

Creating a copy of A as B. Overwriting A/B also changes B/A

A = ["u", "w", "x", "y", "z"]
B = A  # create a copy of object A. shared memory address
assert A is B
A[:] = ["1k", "2k", "3k"]  # A is overwritten, which means B is also
# A after overwriting A
print(A)  # ['1k', '2k', '3k']
# B after overwriting A
print(B)  # ['1k', '2k', '3k']
assert A is B
assert hex(id(A)) == hex(id(B))  # same location in memory

Striding: list[start:end:stride]

Odd indices (1, 3, 5, …)

pp = ["electron", "muon", "tau", "gluon", "photon", "strange"]
odd_indices = pp[1::2]
print(odd_indices)
# ['muon', 'gluon', 'strange']

Even indices (0, 2, 4, …)

even_indices = pp[::2]
print(even_indices)
# ['electron', 'tau', 'photon']

Reversing an iterable

print(pp[::-1])
# ['strange', 'photon', 'gluon', 'tau', 'muon', 'electron']
palindrome = "kayak"
assert palindrome == palindrome[::-1]

Reverse and take every second element

nums = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print(nums[::-2])  # [9, 7, 5, 3, 1]
# in two steps for more clarity: first reverse, then stride
nums_reversed = nums[::-1]
print(nums_reversed[::2])  # [9, 7, 5, 3, 1]
assert nums[::-2] == nums_reversed[::2]