Week 6: Lists & Slicing

4360 words
22 min read
2026-09-12T00:00:00.000Z
Python Week 1: the first filter for runtime behavior
Visual companion
Python
Type and operator map

Python Week 1: the first filter for runtime behavior

View
Revision summary

What this note is really saying

Short form

Lists as mutable sequences, 0-based indexing, slicing [start:stop:step], list methods, and shallow copy vs aliasing. # Programming in Python — Week 6: Lists & Slicing The official IITM syllabus lists **Week 6: Basic Collections in Python**.

Programming in Python — Week 6: Lists & Slicing

The official IITM syllabus lists Week 6: Basic Collections in Python.
This week changes the scale of your programs. Instead of keeping one value in one variable, Python can keep many related values inside one collection.

TL;DR

Before collections:
python
a = 10
b = 20
c = 30
With a collection:
python
values = [10, 20, 30]
Now we can:
  • store many values together
  • access individual elements
  • iterate through them
  • modify them
  • search them
  • count them
  • slice subsequences
  • build new collections
  • combine collections with loops and conditions
The central model is:
collection=multiple values grouped into one object\boxed{ \text{collection} = \text{multiple values grouped into one object} }
The most important Python collection for this week is the list.

1. Why collections?

Suppose we have marks of five students.
Without a collection:
python
m1 = 67
m2 = 81
m3 = 45
m4 = 90
m5 = 73
This becomes inconvenient if there are:
10001000
students.
With a list:
python
marks = [67, 81, 45, 90, 73]
Now the data has one name:
python
marks
and can be processed systematically.

2. List

A Python list is an ordered collection of elements.
Example:
python
numbers = [10, 20, 30, 40]
The order matters.
Conceptually:
text
index:    0   1   2   3
value:   10  20  30  40

3. Zero-based indexing

Python lists use zero-based indexing.
For:
python
numbers = [10, 20, 30, 40]
we have:
python
numbers[0]   # 10
numbers[1]   # 20
numbers[2]   # 30
numbers[3]   # 40
So the first element is at index:
00
not 1.

4. Last valid positive index

For a list of length:
n,n,
valid non-negative indices are:
0,1,2,…,n−1.0,1,2,\dots,n-1.
So:
last index=n−1\boxed{ \text{last index}=n-1 }

5. len()

Python:
python
len(values)
returns the number of elements.
Example:
python
values = [5, 8, 2, 9]
print(len(values))
Output:
text
4

6. Accessing elements

python
x = [4, 7, 9]

print(x[0])
print(x[2])
Output:
text
4
9

7. Index vs value

For:
python
x = [4, 7, 9]
in:
python
x[1]
1 is the index.
7 is the value stored at that index.
Do not confuse:
text
position/index
with:
text
element/value

8. Index error

For:
python
x = [4, 7, 9]
valid positive indices are:
text
0, 1, 2
So:
python
x[3]
is out of bounds and raises an error.

9. Negative indexing

Python also supports negative indices.
For:
python
x = [10, 20, 30, 40]
python
x[-1]   # 40
x[-2]   # 30
x[-3]   # 20
So:
−1=last element\boxed{ -1=\text{last element} }

10. Positive and negative index map

For:
python
x = [10, 20, 30, 40]
text
value:      10   20   30   40
positive:    0    1    2    3
negative:   -4   -3   -2   -1

11. Lists are mutable

A Python list can be changed after creation.
Example:
python
x = [10, 20, 30]

x[1] = 99

print(x)
Output:
text
[10, 99, 30]
This property is called mutability.

12. Mutation

Mutation means changing an existing object.
python
x[1] = 99
changes the list itself.
It does not merely calculate a new temporary value.

13. Different element types

Python lists can contain values of different types:
python
x = [10, "hello", True, 3.5]
However, many numerical algorithms naturally use collections of similar values.

14. Empty list

python
x = []
represents a list containing zero elements.
Its length:
python
len(x)
is:
0.0.

15. Creating a list

Literal syntax:
python
numbers = [1, 2, 3]
Strings:
python
names = ["A", "B", "C"]
Booleans:
python
flags = [True, False, True]

16. Iterating over list values

Instead of:
python
for i in range(len(values)):
    print(values[i])
Python lets us directly iterate over values:
python
for x in values:
    print(x)
This is often cleaner when index itself is unnecessary.

17. Example

python
values = [5, 8, 3]

for x in values:
    print(x)
Output:
text
5
8
3
Loop variable x receives each element in order.

18. Value iteration vs index iteration

Value iteration

python
for x in values:
    print(x)
Use when you only need elements.

Index iteration

python
for i in range(len(values)):
    print(i, values[i])
Use when you need positions as well.

19. Sum a list manually

python
values = [3, 8, 2, 7]

total = 0

for x in values:
    total += x

print(total)
Result:
3+8+2+7=20.3+8+2+7=20.

20. Built-in sum()

Python also provides:
python
sum(values)
Example:
python
values = [3, 8, 2, 7]
print(sum(values))
Output:
text
20
Understanding the manual accumulator remains important for algorithmic reasoning.

21. Average

python
values = [10, 20, 30, 40]

average = sum(values) / len(values)

print(average)
Result:
25.25.
This assumes the list is non-empty.

22. Empty-list danger

For:
python
values = []
this is invalid:
python
sum(values) / len(values)
because:
len(values)=0.len(values)=0.
Always consider the zero-element case.

23. Minimum and maximum

Python provides:
python
min(values)
max(values)
Example:
python
values = [4, 9, 2, 7]

print(min(values))
print(max(values))
Output:
text
2
9

24. Manual maximum

python
maximum = values[0]

for x in values:
    if x > maximum:
        maximum = x
This assumes:
python
values
is non-empty.
The algorithm is the same running-maximum pattern from earlier weeks.

25. Membership with in

Python:
python
x in values
returns a Boolean.
Example:
python
values = [5, 8, 2]

print(8 in values)
print(10 in values)
Output:
text
True
False

26. not in

python
x not in values
is true if the element does not occur.
Example:
python
if 10 not in values:
    print("Missing")

27. Linear search intuition

Membership can be understood as checking elements one by one until:
  • a match is found
  • or the collection ends
Conceptually:
python
found = False

for x in values:
    if x == target:
        found = True
        break

28. Count matches manually

python
count = 0

for x in values:
    if x == target:
        count += 1
This computes how many times target occurs.

29. Built-in .count()

Lists also provide:
python
values.count(target)
Example:
python
values = [2, 5, 2, 2, 8]

print(values.count(2))
Output:
text
3

30. .index()

python
values.index(x)
returns the index of the first occurrence.
Example:
python
values = [5, 8, 3, 8]

print(values.index(8))
Output:
text
1
It finds the first 8.

31. .index() when value is absent

If an element does not exist:
python
values.index(100)
raises an error.
A safe pattern:
python
if 100 in values:
    print(values.index(100))

32. append()

To add one element at the end:
python
values.append(x)
Example:
python
values = [1, 2]

values.append(3)

print(values)
Output:
text
[1, 2, 3]

33. Repeated list construction

python
values = []

for i in range(5):
    values.append(i * i)

print(values)
Output:
text
[0, 1, 4, 9, 16]
This pattern constructs a collection incrementally.

34. Filter into a new list

python
numbers = [3, 8, 5, 10, 2]

evens = []

for x in numbers:
    if x % 2 == 0:
        evens.append(x)

print(evens)
Output:
text
[8, 10, 2]

35. Transformation into a new list

python
numbers = [1, 2, 3, 4]

squares = []

for x in numbers:
    squares.append(x ** 2)
Result:
text
[1, 4, 9, 16]
This is a map-like transformation:
x↦x2.x\mapsto x^2.

36. Filter vs transform

Filter

Keep only some values:
python
if condition:
    result.append(x)

Transform

Create a changed value for every input:
python
result.append(f(x))
These are fundamental collection-processing patterns.

37. insert()

python
values.insert(index, value)
inserts an element at a chosen position.
Example:
python
values = [10, 30]

values.insert(1, 20)

print(values)
Output:
text
[10, 20, 30]
Existing elements shift right.

38. remove()

python
values.remove(x)
removes the first matching value.
Example:
python
values = [2, 5, 2, 9]

values.remove(2)

print(values)
Result:
text
[5, 2, 9]
Only the first 2 is removed.

39. pop()

python
values.pop()
removes and returns the last element.
Example:
python
values = [10, 20, 30]

x = values.pop()
Now:
text
x = 30
values = [10, 20]

40. pop(index)

python
values.pop(1)
removes the element at index 1.
Example:
python
values = [10, 20, 30]

x = values.pop(1)
Then:
text
x = 20
values = [10, 30]

41. del

Python also allows:
python
del values[i]
Example:
python
values = [10, 20, 30]

del values[1]
Result:
text
[10, 30]

42. Remove by value vs position

By value

python
values.remove(20)

By index

python
values.pop(1)
or:
python
del values[1]
Do not confuse these operations.

43. Concatenation

Lists can be combined:
python
a = [1, 2]
b = [3, 4]

c = a + b
Result:
text
[1, 2, 3, 4]

44. Repetition

python
[0] * 5
produces:
text
[0, 0, 0, 0, 0]
Useful for initializing fixed-size simple lists.

45. Slicing

A slice extracts a portion of a sequence.
python
values[start:stop]
Like range, the stop index is excluded.
Example:
python
values = [10, 20, 30, 40, 50]

print(values[1:4])
Output:
text
[20, 30, 40]

46. Slice endpoint rule

For:
python
values[a:b]
indices included are:
a,a+1,…,b−1.a,a+1,\dots,b-1.
Again:
start included, stop excluded\boxed{ \text{start included, stop excluded} }

47. Omitted slice endpoints

python
values[:3]
means from beginning through index 2.
python
values[2:]
means from index 2 through end.

48. Full copy slice

python
values[:]
creates a shallow copy of the list.
This matters because simple assignment behaves differently.

49. Aliasing

Consider:
python
a = [1, 2, 3]
b = a
Now a and b refer to the same list object.
If:
python
b[0] = 99
then:
python
a
also appears as:
text
[99, 2, 3]

50. Assignment does not necessarily copy a list

This:
python
b = a
copies the reference, not the list contents into an independent object.
Conceptually:
text
a ─┐
   ├──> [1,2,3]
b ─┘

51. Shallow copy

A simple independent outer-list copy:
python
b = a[:]
or:
python
b = a.copy()
Now changing:
python
b[0]
does not change:
python
a[0]
for a flat list of immutable elements.

52. Aliasing trace

python
a = [1, 2]
b = a

b.append(3)

print(a)
Output:
text
[1, 2, 3]
because both names reference the same mutable object.

53. Copy trace

python
a = [1, 2]
b = a.copy()

b.append(3)

print(a)
print(b)
Output:
text
[1, 2]
[1, 2, 3]

54. Slicing with step

General form:
python
values[start:stop:step]
Example:
python
values = [0, 1, 2, 3, 4, 5]

values[0:6:2]
produces:
text
[0, 2, 4]

55. Reverse with slicing

python
values[::-1]
returns a reversed copy.
Example:
python
[1, 2, 3][::-1]
gives:
text
[3, 2, 1]

56. Strings are sequences too

A string is also an ordered sequence.
python
text = "python"
Indexes:
text
p y t h o n
0 1 2 3 4 5
So:
python
text[0]
returns:
text
'p'

57. String slicing

python
text = "python"

print(text[1:4])
Output:
text
yth
Same start-inclusive, stop-exclusive principle.

58. Strings are immutable

Unlike lists:
python
text[0] = "P"
is not allowed.
Strings cannot be modified element-by-element.
Instead create a new string.
This is a key difference:
list: mutable\boxed{ \text{list: mutable} } string: immutable\boxed{ \text{string: immutable} }

59. Iterate over characters

python
for ch in "python":
    print(ch)
Output:
text
p
y
t
h
o
n
So loops work over sequences beyond range().

60. Count vowels

python
text = input()
count = 0

for ch in text.lower():
    if ch in "aeiou":
        count += 1

print(count)
This combines:
  • strings
  • iteration
  • membership
  • conditionals
  • counters

61. String membership

python
"a" in "cat"
is:
text
True
and:
python
"z" in "cat"
is:
text
False

62. String concatenation

python
a = "hello"
b = "world"

c = a + " " + b
Result:
text
"hello world"

63. Building strings iteratively

python
result = ""

for ch in text:
    if ch != " ":
        result += ch
This creates a new string without spaces.
Because strings are immutable, each concatenation conceptually constructs a new string value.

64. Tuple

Python also has tuples.
Example:
python
point = (3, 5)
A tuple is ordered, like a list, but typically immutable.

65. Tuple indexing

python
point = (3, 5)

print(point[0])
print(point[1])
Output:
text
3
5

66. Tuple immutability

This is not allowed:
python
point[0] = 10
because tuples are immutable.
So:
TypeOrderedMutable
ListYesYes
TupleYesNo
StringYesNo

67. Tuple packing

python
point = 3, 5
creates a tuple conceptually equivalent to:
python
point = (3, 5)

68. Tuple unpacking

python
x, y = (3, 5)
gives:
text
x = 3
y = 5
This is useful for structured multiple values.

69. Swap revisited

Python:
python
a, b = b, a
uses tuple-like packing/unpacking semantics.
Right side is evaluated first, then values are assigned.

70. Nested collections

Collections can contain other collections.
Example:
python
matrix = [
    [1, 2],
    [3, 4]
]
This is a list containing two lists.

71. Matrix access

python
matrix[0]
gives:
text
[1, 2]
Then:
python
matrix[0][1]
gives:
text
2
First index chooses row.
Second chooses element inside that row.

72. Nested list traversal

python
for row in matrix:
    for x in row:
        print(x)
This uses nested loops to traverse a nested collection.

73. Index-based matrix traversal

python
for i in range(len(matrix)):
    for j in range(len(matrix[i])):
        print(matrix[i][j])
Useful when row/column positions matter.

74. List of strings

python
names = ["Asha", "Ravi", "Meera"]
Then:
python
names[1]
gives:
text
"Ravi"
and:
python
names[1][0]
gives:
text
"R"
because a string itself is a sequence.

75. List methods mutate the list

Consider:
python
x = [3, 1, 2]
x.sort()
Now:
python
x
becomes:
text
[1, 2, 3]
The original list object was modified.

76. sorted()

Python also provides:
python
sorted(x)
which returns a new sorted list without necessarily modifying x.
Example:
python
x = [3, 1, 2]
y = sorted(x)
Then:
text
x = [3, 1, 2]
y = [1, 2, 3]

77. .sort() vs sorted()

.sort()

python
x.sort()
mutates list x.

sorted()

python
y = sorted(x)
returns a sorted result.
This distinction is a classic exam/debugging issue.

78. Reverse

Mutation:
python
x.reverse()
changes the list.
Alternative:
python
x[::-1]
creates a reversed copy.
Again:
mutation vs new object\boxed{ \text{mutation vs new object} }

79. extend()

python
a.extend(b)
adds all elements of b to the end of a.
Example:
python
a = [1, 2]
a.extend([3, 4])
Result:
text
[1, 2, 3, 4]

80. append() vs extend()

Starting:
python
a = [1, 2]

Append

python
a.append([3, 4])
gives:
text
[1, 2, [3, 4]]

Extend

python
a.extend([3, 4])
gives:
text
[1, 2, 3, 4]
Very different results.

81. Nested element created by append

python
a.append([3, 4])
adds one element.
That one element happens to itself be a list.
So length increases by:
11
not 2.

82. List comprehension — useful Python feature

A concise way to build lists:
python
squares = [x ** 2 for x in range(5)]
Result:
text
[0, 1, 4, 9, 16]
This is equivalent in spirit to:
python
squares = []

for x in range(5):
    squares.append(x ** 2)

83. Comprehension with filter

python
evens = [x for x in range(10) if x % 2 == 0]
Result:
text
[0, 2, 4, 6, 8]
This combines transformation/collection construction with filtering.

84. Do not let compact syntax hide the algorithm

When tracing:
python
[x ** 2 for x in values if x > 0]
mentally expand it:
python
result = []

for x in values:
    if x > 0:
        result.append(x ** 2)
The expanded algorithm is easier to reason about.

85. Sequence equality

Lists compare element-by-element.
Example:
python
[1, 2, 3] == [1, 2, 3]
is:
text
True
But:
python
[1, 2, 3] == [3, 2, 1]
is:
text
False
because order matters.

86. Membership checks elements, not positions

For:
python
x = [10, 20, 30]
python
20 in x
asks whether value 20 occurs.
It does not ask whether index 20 exists.

Common mistake: first element index is 1
Wrong:
python
x[1]
if you intend the first element.
Correct:
python
x[0]
Python indexing begins at zero.

Common mistake: last index equals length
For:
python
len(x) == 5
last valid positive index is:
4.4.
So:
python
x[len(x)]
is out of bounds.
Correct last element:
python
x[len(x) - 1]
or:
python
x[-1]

Common mistake: modifying a string element
Wrong:
python
text[0] = "A"
Strings are immutable.
Create a new string instead.

Common mistake: assuming assignment copies list
python
b = a
does not create an independent list copy.
Mutations through one name can appear through the other.

Common mistake:
append returns new list
This pattern is wrong:
python
x = x.append(5)
append() mutates x; it does not return the new list for assignment in the way beginners often expect.
After this, x can become:
python
None
because the method's return value is assigned back.
Correct:
python
x.append(5)

92. Same issue with .sort()

Wrong:
python
x = x.sort()
Correct:
python
x.sort()
or:
python
x = sorted(x)
Know whether an operation mutates or returns a new collection.

Common mistake: remove by index
python
x.remove(2)
means:
remove the first value equal to 2
not:
remove index 2
Use:
python
x.pop(2)
or:
python
del x[2]
for position-based removal.

Common mistake: modifying list while iterating over it
Example:
python
for x in values:
    if x < 0:
        values.remove(x)
This can behave unexpectedly because list positions shift during traversal.
A safer pattern is often to build a new filtered list:
python
result = []

for x in values:
    if x >= 0:
        result.append(x)

Common mistake: slice stop assumed inclusive
python
x[1:4]
contains indices:
1,2,31,2,3
not index 4.
Same half-open interval logic as range().

Common mistake: confuse append and concatenate
Starting:
python
x = [1, 2]
python
x.append([3, 4])
and:
python
x = x + [3, 4]
do not produce the same structure.
First:
text
[1, 2, [3, 4]]
Second:
text
[1, 2, 3, 4]

Common mistake: nested indexing order
For:
python
matrix[i][j]
read it as:
  1. retrieve matrix[i]
  2. from that inner collection retrieve [j]
Do not treat it as one magical two-dimensional primitive.

Common mistake: empty collection assumptions
Functions like:
python
min([])
max([])
have no meaningful ordinary result and raise errors.
Always check whether an algorithm requires a non-empty collection.

99. Worked trace — mutation

python
x = [2, 4, 6]

x.append(8)
x[1] = 10
x.pop()

print(x)
Trace:
text
[2,4,6]
↓ append 8
[2,4,6,8]
↓ x[1] = 10
[2,10,6,8]
↓ pop()
[2,10,6]
Output:
text
[2, 10, 6]

100. Worked trace — aliasing

python
a = [1, 2]
b = a

a.append(3)
b[0] = 9

print(a)
print(b)
Both names refer to same object.
Final:
text
[9, 2, 3]
[9, 2, 3]

101. Worked trace — copy

python
a = [1, 2]
b = a.copy()

a.append(3)
b[0] = 9
Final:
text
a = [1, 2, 3]
b = [9, 2]
Different objects.

102. Worked trace — filtering

python
x = [5, -2, 7, 0, -1]
y = []

for value in x:
    if value >= 0:
        y.append(value)
Trace:
  • 5 → keep
  • -2 → skip
  • 7 → keep
  • 0 → keep
  • -1 → skip
Final:
text
[5, 7, 0]

103. Worked trace — transformation

python
x = [1, 3, 5]
y = []

for value in x:
    y.append(value + 2)
Final:
text
[3, 5, 7]
Input collection remains:
text
[1, 3, 5]

104. Collection-processing pipeline

A useful mental model:
text
collection
    ↓
iterate
    ↓
filter?
    ↓
transform?
    ↓
accumulate / append
    ↓
result
This pattern appears constantly in Python and later data science.

105. Lists connect iteration to data

Before Week 6:
python
for i in range(10):
mostly meant:
iterate over generated integers.
Now:
python
for student in students:
means:
iterate over actual stored data.
That is a major conceptual transition.

106. Complexity intuition

Accessing:
python
x[i]
is conceptually direct.
But searching:
python
target in x
may need to inspect many elements.
For a list of length nn, a linear search may inspect up to:
nn
elements.
This helps explain why data structure choice eventually matters.

107. Collection invariants

Suppose we build:
python
positives = []
and append only when:
python
x > 0
Then after every iteration:
every element currently in positives is positive.
That invariant helps reason about correctness.

108. Week 5 → Week 6 transition

Week 5:
text
generate/control repeated computation
Week 6:
text
store many values
+
iterate over stored values
+
modify and transform collections
Conceptually:
text
ITERATION
    +
COLLECTIONS
    ↓
DATA PROCESSING

109. Compact list cheat sheet

python
x = [10, 20, 30]

len(x)

x[0]
x[-1]

x[1] = 99

x.append(40)
x.insert(1, 15)

x.remove(20)
x.pop()
x.pop(1)

10 in x

x.count(10)
x.index(10)

x[1:3]
x[::-1]

x.sort()
sorted(x)

x.copy()

110. Core collection patterns

Traverse values

python
for x in values:
    ...

Traverse indices

python
for i in range(len(values)):
    ...

Filter

python
result = []

for x in values:
    if condition:
        result.append(x)

Transform

python
result = []

for x in values:
    result.append(f(x))

Reduce / accumulate

python
total = 0

for x in values:
    total += x
python
for x in values:
    if x == target:
        ...
        break

111. What you should actually master

By the end of Python Week 6, you should be able to:
  1. Explain why collections are useful.
  2. Create Python lists.
  3. Understand zero-based indexing.
  4. Use positive and negative indices.
  5. Use len().
  6. Access and modify list elements.
  7. Understand list mutability.
  8. Traverse lists directly.
  9. Traverse lists by index.
  10. Sum/count/filter/search collection values.
  11. Use membership with in.
  12. Use append, insert, remove, pop, and del.
  13. Distinguish removal by value from removal by index.
  14. Concatenate lists.
  15. Slice lists.
  16. Understand stop-exclusive slice semantics.
  17. Understand aliasing.
  18. Make a simple independent list copy.
  19. Distinguish .sort() from sorted().
  20. Distinguish append() from extend().
  21. Treat strings as immutable sequences.
  22. Iterate and slice strings.
  23. Understand basic tuples and unpacking.
  24. Work with nested lists.
  25. Combine collections with loops and conditionals.
  26. Recognize common mutation-related bugs.
If these are comfortable, Programming in Python Week 6 is under control.

Quick Recall & Flashcards

Test your active recall before proceeding to practice problems. Format:
Question :: Answer.
  • Week 6 Diagnostic: For list L = [1, 2, 3, 4, 5], what does L[1:4] return? :: Answer: A — Slicing L[1:4] includes index 1, 2, 3 (values 2, 3, 4) and excludes index 4.
  • Week 6 Diagnostic: If A = [1, 2], and B = A, and then B.append(3) is run, what is the length of A? :: Answer: 3 — B = A creates an alias to the exact same list in memory. Modifying B mutates A, so len(A) = 3.

Practice & Self-Check

Attempt these diagnostic questions to verify your operational understanding.
1

Question 1

For list L = [1, 2, 3, 4, 5], what does L[1:4] return?
MCQ
3 Unit Assessment
A. [2, 3, 4]
B. [1, 2, 3]
C. [2, 3, 4, 5]
D. [1, 2, 3, 4]
2

Question 2

If A = [1, 2], and B = A, and then B.append(3) is run, what is the length of A?
NAT
3 Unit Assessment

Active Recall Session

Document outline

Keep your place and jump directly to a heading.

Table of contents

No note selected

Open a chapter to see its outline, backlinks, and sources here.