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.
Prefer to see lists of numbers handled in a spreadsheet as well? The Excel AI Mastery: 100 Formulas course on NextGenTemplates Academy covers sorting, filtering and summing with practice files.
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



