Python with AI Tutorial · Chapter 13 of 48
Python lists are ordered, changeable collections written in square brackets, such as ["Laptop", "Monitor", "Mouse"]. They are the workhorse data structure of the language: a column of sales figures, a queue of tasks, the rows read from a CSV file. This chapter shows how to create Python lists and how to access, add, remove, sort and copy their items safely.
Creating and accessing a list
Write the items between square brackets, separated by commas. Items keep the order you gave them and are reached by index, counting from 0 at the front and -1 at the back. Slicing works exactly as it does for strings.
products = ["Laptop", "Monitor", "Keyboard", "Mouse"]
print(products)
print(products[0])
print(products[-1])
print(products[1:3])
print(len(products))
Output: ['Laptop', 'Monitor', 'Keyboard', 'Mouse'] Laptop Mouse ['Monitor', 'Keyboard'] 4
A list can hold any mix of types, including other lists, and it may be empty: []. The list() function builds one from any other sequence, so list("abc") gives ['a', 'b', 'c'] and list(range(5)) gives [0, 1, 2, 3, 4].
Changing items
Unlike strings, lists are mutable: assign to an index to replace one item, or assign to a slice to replace several at once.
prices = [899, 249, 45, 25]
prices[2] = 49
prices[0:2] = [879, 239]
print(prices)
Output: [879, 239, 49, 25]
Adding items
append() adds one item to the end, insert() puts an item at a given position and extend() adds every item from another collection. All three change the list in place and return None.
team = ["Anita", "Rahul"]
team.append("Meera")
team.insert(0, "Sanjay")
team.extend(["Vikram", "Priya"])
print(team)
Output: ['Sanjay', 'Anita', 'Rahul', 'Meera', 'Vikram', 'Priya']
Watch the difference between append and extend. team.append(["Vikram", "Priya"]) would add a single item that is itself a list, giving a nested structure you probably did not want.
Removing items
remove() deletes the first item with a matching value, pop() removes an item by position and returns it (the last item by default), del deletes by index or slice and clear() empties the list.
team = ['Sanjay', 'Anita', 'Rahul', 'Meera', 'Vikram', 'Priya']
team.remove("Rahul")
last = team.pop()
first = team.pop(0)
del team[1]
print(team)
print(last, first)
Output: ['Anita', 'Vikram'] Priya Sanjay
Because pop() returns the value, it is the natural way to take the next task off a to-do list: task = queue.pop(0).
Python list methods
| Method | What it does | Returns |
|---|---|---|
append(x) |
Add x to the end |
None |
insert(i, x) |
Insert x at index i |
None |
extend(iterable) |
Add every item from another collection | None |
remove(x) |
Delete the first item equal to x |
None (ValueError if missing) |
pop(i=-1) |
Remove and return the item at i |
The item |
clear() |
Remove every item | None |
index(x) |
Position of the first x |
int (ValueError if missing) |
count(x) |
How many items equal x |
int |
sort(key=None, reverse=False) |
Sort in place | None |
reverse() |
Reverse the order in place | None |
copy() |
Shallow copy of the list | A new list |
Sorting
sort() rearranges the list in place and returns None; sorted() leaves the original alone and returns a new sorted list. Both accept reverse=True and a key function that tells Python what to compare.
sales = [1200, 980, 1500, 430]
sales.sort()
print(sales)
sales.sort(reverse=True)
print(sales)
names = ["meera", "Zoe", "anita"]
print(sorted(names))
print(sorted(names, key=str.lower))
employees = [("Anita", 52000), ("Rahul", 48000), ("Meera", 61000)]
employees.sort(key=lambda e: e[1], reverse=True)
print(employees)
Output:
[430, 980, 1200, 1500]
[1500, 1200, 980, 430]
['Zoe', 'anita', 'meera']
['anita', 'meera', 'Zoe']
[('Meera', 61000), ('Anita', 52000), ('Rahul', 48000)]
The plain sorted(names) result looks wrong because upper-case letters sort before lower-case ones. Passing key=str.lower compares lower-cased copies while keeping the original spelling in the output.
Ask the assistant to sort a realistic list of records several different ways and to explain the key function each time.
I have this Python list of orders: [("ORD-7", "Acme", 1250.5, "2026-03-14"), ("ORD-2", "Bright Co", 830, "2026-01-30"), ("ORD-5", "Acme", 2100, "2026-02-02")]. Show me how to sort it by amount descending, by customer name then date, and by the number in the order ID. Use sorted() with a key function each time, print the results, and explain in one sentence per example what the key function returns.
Looping and list comprehensions
A for loop visits each item in order. A list comprehension builds a new list from an existing one in a single expression, optionally with a filter, and is the most common way to transform data in Python.
amounts = [1200, 980, 1500, 430]
for amount in amounts:
print(f"{amount * 1.18:.2f}")
with_tax = [round(a * 1.18, 2) for a in amounts]
print(with_tax)
big = [a for a in amounts if a > 1000]
print(big)
Output: 1416.00 1156.40 1770.00 507.40 [1416.0, 1156.4, 1770.0, 507.4] [1200, 1500]
Built-in functions for lists
Several built-ins work directly on lists of numbers or strings, and membership testing with in is the quickest way to check whether a value is present.
sales = [1200, 980, 1500, 430, 980]
print(min(sales), max(sales), sum(sales))
print(sales.count(980))
print(sales.index(1500))
print(980 in sales)
Output: 430 1500 5090 2 2 True
Copying a list
Assigning a list to a new name does not copy it; both names point at the same object, so a change through one name shows up through the other. Use copy(), slicing [:] or list() to get an independent copy.
original = [1, 2, 3]
alias = original
backup = original.copy()
alias.append(4)
print(original)
print(backup)
Output: [1, 2, 3, 4] [1, 2, 3]
=. In the example above alias and original are the same list, which is why appending to one changed the other. This bites hardest when a function modifies a list passed in as an argument, or when a list is used as a default parameter value; the same list object is then shared across every call.Nested lists
A list of lists models a table: each inner list is a row. Use two indexes to reach a cell, and unpack the inner list directly in a for loop to give each column a name.
invoices = [
["INV-101", "Acme Ltd", 1250.00],
["INV-102", "Bright Co", 830.50],
]
print(invoices[1][1])
print(invoices[0][2] + invoices[1][2])
for inv_id, customer, amount in invoices:
print(f"{inv_id}: {customer} owes {amount:,.2f}")
Output: Bright Co 2080.5 INV-101: Acme Ltd owes 1,250.00 INV-102: Bright Co owes 830.50
Once your rows have more than three or four columns, a list of dictionaries or a pandas DataFrame is easier to read than a list of lists, and both are covered later in the course.
Describe a small list-processing task from your own work and ask for the solution in three styles, then compare them.
Using Python 3.12, I have a list of daily sales for one month: [420, 0, 515, 610, 0, 380, 725, 0, 460, 590]. Show me three ways to (a) remove the zero days, (b) add 18% tax to each remaining value rounded to 2 decimals, and (c) find the three best days: first with a plain for loop, then with a list comprehension, then with filter() and map(). Explain which version you would use in production and why. Do not use pandas.
Common mistakes
- Writing
names = names.sort()ornames = names.append(x). Both methods returnNone, sonamesis wiped out. - Copying a list with
=and then wondering why both variables changed. - Calling
remove()orindex()on a value that is not there, which raisesValueError. Check withinfirst. - Removing items from a list while looping over it, which skips elements. Build a new filtered list instead.
- Confusing
append()withextend()and ending up with a list inside a list.
Exercise
Monthly sales for the first half of the year are [42000, 39500, 51000, 36800, 47250, 44100]. Remove the weakest month, add July’s figure of 49900, sort the list from highest to lowest, then print the top three months and the total.
Show answer
monthly = [42000, 39500, 51000, 36800, 47250, 44100]
monthly.remove(min(monthly))
monthly.append(49900)
monthly.sort(reverse=True)
print(monthly[:3])
print(sum(monthly))
Output: [51000, 49900, 47250] 273750
min(monthly) finds the value to remove and remove() deletes it, so you never need to know its position.
Related chapters
- Python Tuples – the immutable cousin of the list.
- Python For Loops – iterating over lists in depth.
- Python Dictionaries – when rows need named fields.
- Python with AI course hub – all 48 chapters in order.
FAQ
What is the difference between append() and extend()?
append() adds exactly one item, even if that item is itself a list. extend() takes an iterable and adds each of its items individually, so extending with a three-item list makes the list three items longer.
What is the difference between sort() and sorted()?
sort() is a list method that reorders the list in place and returns None. sorted() is a built-in function that works on any iterable and returns a new sorted list, leaving the original unchanged.
How do I copy a list in Python?
Use new_list = old_list.copy(), old_list[:] or list(old_list). All three make a shallow copy. Plain assignment with = only creates a second name for the same list, so changes appear in both.
Working with spreadsheets too? Ready-made Excel, Google Sheets and Power BI templates are at NextGenTemplates.com.
Chapter 13 of 48 · Python with AI: all 48 chapters



