Python · Beginner
Lists in Python
In short: A Python list is an ordered, changeable collection written in square brackets, such as [3, 1, 2]. You reach items by zero-based index, add with append() and insert(), remove with remove() and pop(), reorder with sort(), and process every item with a for loop. A list can hold values of any type, including other lists.
An ordered collection you can change
When a program handles more than a handful of related values, giving each its own variable stops working: you cannot write a loop over score1, score2, score3. A list holds any number of values in a definite order under one name. Items are reached by their position, counting from 0, exactly as characters in a string are. Unlike a string, a list is mutable: you can replace an item, add to either end, insert in the middle, remove and reorder, all without creating a new list.
Lists are created with square brackets, [] for an empty one, or with list() from another sequence such as a string or a range. len() counts items, in tests membership, and slicing with [a:b] gives a new list containing part of the original. The most used methods change the list in place: append(x) adds x at the end; insert(i, x) puts x at position i and shifts the rest along; remove(x) deletes the first item equal to x; pop() removes and returns the last item, or the item at an index you pass; sort() reorders the items; reverse() flips them. Because these methods modify the list rather than building a new one, they return None, and writing numbers = numbers.sort() throws the list away. The built-in sorted(numbers) is the alternative when you want a sorted copy and the original untouched.
Built-in functions summarise a list of numbers: sum(), min() and max(). A for loop visits each item, and enumerate() supplies the position too, as the loops lesson showed.
Since a list is a single object that several names can refer to, b = a does not copy it; both names see every change. Copy with a.copy(), list(a) or the slice a[:] when you need an independent list. Items may be of different types, and a list may contain other lists, which is how a grid or a table of rows is represented: grid[row][col].
Syntax
items = [] # empty list
items = ["tea", "scone", "jam"] # literal
items[0] items[-1] # first, last
items[1:3] # slice -> a new list
items.append(x) items.insert(i, x)
items.remove(x) items.pop() items.pop(i)
items.sort() items.reverse() # in place, return None
sorted(items) # a new sorted list
len(items) sum(items) min(items) max(items) x in itemsIndexes run from 0 to len(items) - 1; negative indexes count back from the end.
List operations: in place or new?
| Operation | Changes the list? | Returns |
|---|---|---|
| append(x) | yes | None |
| insert(i, x) | yes | None |
| remove(x) | yes | None |
| pop(i) | yes | the removed item |
| sort() | yes | None |
| sorted(items) | no | a new sorted list |
| items[a:b] | no | a new list |
| items.copy() | no | an independent copy |
Adding and removing from a queue
A waiting list at a clinic changes as people arrive, are served and leave.
queue = ["Ines", "Tomas", "Aya"]
print(queue[0], queue[-1], len(queue))
queue.append("Ravi")
queue.insert(1, "Lena")
print(queue)
served = queue.pop(0)
print("Served:", served)
queue.remove("Aya")
queue[0] = "Lena B."
print(queue)
print("Ravi" in queue, "Aya" in queue)Output
Ines Aya 3 ['Ines', 'Lena', 'Tomas', 'Aya', 'Ravi'] Served: Ines ['Lena B.', 'Tomas', 'Ravi'] True False
append adds at the end and insert(1, ...) pushes Tomas and Aya one place to the right. pop(0) removes the first item and hands it back so it can be printed. remove looks for a value, not a position. Assigning to queue[0] replaces an item in place, something a string cannot do. Every one of these operations changed the same list object; nothing was copied.
Sorting, slicing and summarising
Five temperature readings, then a list of words where case affects the order.
temps = [18.5, 22.0, 19.5, 25.0, 21.0]
print(temps[1:3])
print(sum(temps) / len(temps))
print(max(temps), min(temps))
top = sorted(temps, reverse=True)
print(top[:2])
print(temps)
temps.sort()
print(temps)
words = ["pear", "Apple", "fig", "Zest"]
words.sort()
print(words)
words.sort(key=str.lower)
print(words)Output
[22.0, 19.5] 21.2 25.0 18.5 [25.0, 22.0] [18.5, 22.0, 19.5, 25.0, 21.0] [18.5, 19.5, 21.0, 22.0, 25.0] ['Apple', 'Zest', 'fig', 'pear'] ['Apple', 'fig', 'pear', 'Zest']
sorted() returns a new list and leaves temps in its original order, as the fifth line shows; sort() then reorders temps itself. reverse=True sorts descending, and slicing the first two gives the two warmest readings. Strings sort by character code, which places every capital letter before every lower-case one; key=str.lower tells sort to compare lower-cased versions instead, giving the order a person expects.
Building a list from input
The first input line says how many dish names follow: 4, then soup, bread, salad, tart.
count = int(input())
dishes = []
for _ in range(count):
dishes.append(input())
for position, dish in enumerate(dishes, start=1):
print(f"{position}. {dish}")
short = []
for dish in dishes:
if len(dish) <= 4:
short.append(dish)
print("Short names:", short)
menu = dishes.copy()
menu.append("tea")
print(len(dishes), len(menu))Input given to the program: 4 ↵ soup ↵ bread ↵ salad ↵ tart
Output
1. soup 2. bread 3. salad 4. tart Short names: ['soup', 'tart'] 4 5
The first line of input says how many follow, so a for over range(count) reads exactly that many and appends each. The filtering loop is the standard way to build one list from another: start empty, append what qualifies. copy() gives menu its own list, so appending to it leaves dishes at four items; with menu = dishes both would have grown.
Common mistakes
Assigning the result of sort() or append()
Why it goes wrong: These methods change the list and return None, so
items = items.sort()replaces your list with None and the next line that uses it fails.Fix: Call the method on its own line, or use sorted() when you want a new list.
Python · fixitems = [3, 1, 2] items.sort() print(items) ranked = sorted(items, reverse=True)Indexing past the end
Why it goes wrong: A list of 3 items has indexes 0, 1 and 2;
items[3]raises IndexError. Loops that userange(len(items) + 1)or that readitems[i + 1]on the last item hit this.Fix: Use
for item in itemswhere possible, and checki + 1 < len(items)before looking ahead.Copying a list with =
Why it goes wrong:
backup = itemsgives a second name for the same list; sorting or appending through either name affects both.Fix: Use
items.copy()orlist(items)for an independent copy.Confusing append() with extend()
Why it goes wrong:
a.append([4, 5])adds one item that is itself a list, giving[1, 2, 3, [4, 5]]. extend adds each element separately.Fix: Use extend (or
+=) to add several items from another list.Python · fixa = [1, 2, 3] a.extend([4, 5]) print(a) # [1, 2, 3, 4, 5]
Where you use this
Most data a program processes arrives as a series of records: readings from a sensor, lines from a log, scores in a competition. Reading them into a list is the first step, and from there the same handful of operations answers nearly every question. Sort to find the top three, sum and divide for the average, loop with a condition to filter, index() to find where something is. A list of lists represents a table, with rows[2][0] picking the first column of the third row. Once these operations are comfortable, dictionaries add lookup by key, and comprehensions shorten the build-a-list-with-a-loop pattern to a single line.
scores = [72, 95, 88, 61]
scores.sort(reverse=True)
print(scores[:3])
print(sum(scores) / len(scores))Key points
- Lists are ordered, mutable and written with square brackets; indexes start at 0.
append,insert,remove,sortandreversechange the list in place and return None;popreturns the removed item.sorted()and slices give new lists; the original is untouched.sum,min,maxandlensummarise;intests membership.b = amakes an alias; usea.copy()for an independent list.- Build a filtered list by starting with
[]and appending inside a loop.
Try it yourself
The program reads three integers into a list. Print the list sorted in ascending order, then a line Total: followed by the sum of the values.
values = []
for _ in range(3):
values.append(int(input()))
# print the sorted list, then the total
9 ↵ 3 ↵ 4[3, 4, 9]
Total: 16values = []
for _ in range(3):
values.append(int(input()))
values.sort()
print(values)
print("Total:", sum(values))
Practise this
Related lessons
- Strings in PythonWorking with text in Python: indexing and slicing strings, methods such as strip(), split(), replace() and join(), and formatting output with f-strings.9 min
- Loops in Python: for and whileHow a for loop walks through a sequence and a while loop repeats until a condition fails, with range(), enumerate(), break and continue explained by example.9 min
- Tuples in PythonHow Python tuples work: building fixed records, unpacking values into names, returning several results from a function and using tuples as dictionary keys.8 min
- Dictionaries in PythonHow Python dictionaries map keys to values: creating and updating entries, safe lookup with get, iterating items in insertion order, counting and grouping.9 min
Frequently asked questions
What is the difference between append() and extend()?
append(x) adds x as a single new item, even if x is a list. extend(other) walks through other and adds each of its elements individually. So appending [2, 3] to [1] gives [1, [2, 3]], while extending gives [1, 2, 3]. a += other behaves like extend.
Why does my_list.sort() return None?
Because it sorts the list in place, and Python's convention is that methods which modify an object in place return None rather than the object, to make it obvious that no copy was made. If you want the sorted result as a value, use sorted(my_list), which builds and returns a new list and leaves the original as it was.
How do I copy a list in Python?
new = old.copy(), new = list(old) and new = old[:] all create a new list with the same items. These are shallow copies: if the items are themselves lists, both copies still share those inner lists. For a fully independent copy of nested data use copy.deepcopy(old) from the standard library.
How this page was checked. Every program on it was run with CPython 3.11 at build time; runs in your browser on CPython 3.14 (Pyodide) by the publishing checks, and the output shown is what it printed. The Run buttons execute the same code on your device; nothing you type is sent anywhere.