Skip to main content

Chapter 6 - Lists (Python)

Here's a concise walkthrough of the main ideas in Chapter 6, each with a small example.


List basics

A list stores an ordered collection of items in square brackets, and a single variable can hold the whole list.

Example:

spam = ['cat', 'bat', 'rat', 'elephant']
print(spam) # ['cat', 'bat', 'rat', 'elephant']
empty = []

Indexes and nested lists

Indexes start at 0; spam[0] is the first item, spam[1] the second, etc., and you can index into nested lists with multiple brackets.

Example:

spam = ['cat', 'bat', 'rat', 'elephant']
print(spam[0]) # 'cat'
print(spam[3]) # 'elephant'

grid = [['cat', 'bat'], [10, 20, 30]]
print(grid[0]) # ['cat', 'bat']
print(grid[0][1]) # 'bat'
print(grid[1][2]) # 30

Using an index too large raises IndexError.


Negative indexes

Negative indexes count from the end: -1 is last, -2 second to last, and so on.

Example:

spam = ['cat', 'bat', 'rat', 'elephant']
print(spam[-1]) # 'elephant'
print(spam[-3]) # 'bat'

Slices

A slice spam[start:end] returns a new list from start up to but not including end, and you can omit either index.

Example:

spam = ['cat', 'bat', 'rat', 'elephant']
print(spam[1:3]) # ['bat', 'rat']
print(spam[:2]) # ['cat', 'bat']
print(spam[1:]) # ['bat', 'rat', 'elephant']
print(spam[:]) # full copy

len() with lists

len() returns how many items are in the list.

Example:

spam = ['cat', 'dog', 'moose']
print(len(spam)) # 3

Updating items

You can assign to an index to change that item's value.

Example:

spam = ['cat', 'bat', 'rat', 'elephant']
spam[1] = 'aardvark'
spam[-1] = 12345
print(spam) # ['cat', 'aardvark', 'rat', 12345]

List concatenation and replication

+ joins lists into a new list, and * repeats a list.

Example:

print([1, 2, 3] + ['A', 'B'])   # [1, 2, 3, 'A', 'B']
print(['X', 'Y'] * 3) # ['X', 'Y', 'X', 'Y', 'X', 'Y']

del to remove by index

del deletes the item at a given index, shifting later items left.

Example:

spam = ['cat', 'bat', 'rat', 'elephant']
del spam[2]
print(spam) # ['cat', 'bat', 'elephant']

Using lists instead of many variables

Lists avoid a pile of nearly identical variables and scale with any number of items.

Example (dynamic cat list):

cat_names = []
while True:
print('Enter the name of cat ' + str(len(cat_names) + 1) + ' (or enter nothing to stop):')
name = input('>')
if name == '':
break
cat_names = cat_names + [name]

print('The cat names are:')
for name in cat_names:
print(' ' + name)

for loops over lists and range(len())

for loops iterate over each item in a list; range(len(list)) lets you loop over indexes.

Example:

supplies = ['pens', 'staplers', 'flamethrowers', 'binders']

for item in supplies:
print(item)

for i in range(len(supplies)):
print('Index', i, 'is', supplies[i])

in and not in

in and not in test membership and return Booleans.

Example:

spam = ['hello', 'hi', 'howdy']
print('hi' in spam) # True
print('cat' not in spam) # True

Simple pet checker:

my_pets = ['Zophie', 'Pooka', 'Fat-tail']
name = input('Enter a pet name: ')
if name not in my_pets:
print('I do not have a pet named ' + name)
else:
print(name + ' is my pet.')

Multiple assignment (tuple unpacking)

You can unpack list (or tuple) items into separate variables in one line.

Example:

cat = ['fat', 'gray', 'loud']
size, color, disposition = cat
print(size, color, disposition) # fat gray loud

enumerate for index and item

enumerate(list) gives (index, item) pairs each loop iteration.

Example:

supplies = ['pens', 'staplers', 'flamethrowers', 'binders']
for index, item in enumerate(supplies):
print('Index', index, 'in supplies is:', item)

random.choice and random.shuffle

random.choice picks a random item; random.shuffle randomly reorders the list in place.

Example:

import random

pets = ['Dog', 'Cat', 'Moose']
print(random.choice(pets))

people = ['Alice', 'Bob', 'Carol', 'David']
random.shuffle(people)
print(people)

Augmented assignment with lists

Operators like += and *= are shortcuts that modify variables, and work with lists and strings as well.

Example:

spam = 'Hello'
spam += ', world!'
print(spam) # Hello, world!

bacon = ['Zophie']
bacon *= 3
print(bacon) # ['Zophie', 'Zophie', 'Zophie']

List methods: index, append, insert

  • index(x) returns the index of x (first occurrence).
  • append(x) adds x to the end.
  • insert(i, x) inserts x at index i.

Example:

spam = ['hello', 'hi', 'howdy', 'heyas']
print(spam.index('howdy')) # 2

spam.append('yo')
spam.insert(1, 'greetings')
print(spam)

remove and sort and reverse

  • remove(x) deletes the first occurrence of x.
  • sort() sorts in place; sort(reverse=True) reverses order; sort(key=str.lower) gives case-insensitive order.
  • reverse() just reverses the list.

Example:

spam = ['cat', 'bat', 'rat', 'cat']
spam.remove('cat')
print(spam) # ['bat', 'rat', 'cat']

nums = [2, 5, 3.14, 1, -7]
nums.sort()
print(nums) # [-7, 1, 2, 3.14, 5]

animals = ['cats', 'Ants', 'dogs']
animals.sort(key=str.lower)
print(animals)

spam = ['cat', 'dog', 'moose']
spam.reverse()
print(spam) # ['moose', 'dog', 'cat']

Lists across multiple lines and line continuation

Lists (and other bracketed expressions) can span lines; \ is a line-continuation character for other long statements.

Example:

spam = [
'apples',
'oranges',
'bananas',
'cats',
]

print('Four score and seven ' + \
'years ago...')

Short-circuiting and list safety

and and or short-circuit: they may skip evaluating the right side, which is useful for safe index checks.

Example (avoid IndexError):

spam = []
if len(spam) > 0 and spam[0] == 'cat':
print('A cat is the first item.')
else:
print('The first item is not a cat.')

If len(spam) == 0, Python never evaluates spam[0] because the left side of and is False.


Magic 8-ball with a list

A cleaner Magic 8-ball uses a list of messages plus random.choice.

Example:

import random

messages = [
'It is certain',
'Ask again later',
'Very doubtful',
]

input('Ask a yes/no question:\n>')
print(random.choice(messages))

Sequence types and string/list similarity

Strings, lists, ranges, and tuples are all sequence types, supporting indexing, slicing, len, for loops, and in/not in.

Example with a string:

name = 'Zophie'
print(name[0]) # 'Z'
print(name[0:4]) # 'Zoph'
print('Zo' in name) # True
for ch in name:
print('* ' + ch + ' *')

Mutable vs immutable; tuples

Lists are mutable (changeable), strings and tuples are immutable (cannot be changed in place).

Tuple basics:

eggs = ('hello', 42, 0.5)
print(eggs[1:3]) # (42, 0.5)
# eggs[1] = 99 # TypeError: tuple is immutable

Single-item tuple needs a trailing comma:

type(('hello',))   # <class 'tuple'>
type(('hello')) # <class 'str'>

Converting between list, tuple, and string

list() and tuple() convert sequences; list('hello') splits to characters.

Example:

print(tuple(['cat', 'dog', 5]))   # ('cat', 'dog', 5)
print(list(('cat', 'dog', 5))) # ['cat', 'dog', 5]
print(list('hello')) # ['h', 'e', 'l', 'l', 'o']

References and shared lists

Variables hold references to values; assigning one list variable to another copies the reference, so both names point to the same list.

Example:

spam = [0, 1, 2, 3]
eggs = spam # same list
eggs[1] = 'Hello!'
print(spam) # [0, 'Hello!', 2, 3]
print(eggs) # [0, 'Hello!', 2, 3]

Changing eggs changed spam because there is only one underlying list.


Overall idea of the chapter

The chapter's main message is: lists are one of Python's most useful data structures. They let you store, access, modify, and organize collections of values with indexing, slicing, and a rich set of methods. Understanding mutability, references, and the difference between sequences is key to avoiding subtle bugs.