Python Lists: Methods, Slicing, Sorting, append, Tuples and Sets
A Python list (list) is an ordered, mutable collection of any values in square brackets, for example [250, 1200, 99]: you can add items with append, insert, remove and slice them, and sort them. The sort method sorts a list in place and returns None, while the sorted function returns a new sorted list.
A Python list (list) is an ordered set of any values in square brackets, which you can change: add items to the end, insert them in the middle, remove them, sort them. It is the most commonly used collection in the language: lines of a file, expenses for a month, API responses — almost everything starts as a list. Let us go through the Python list in full: creating it, methods, slicing, sorting, list comprehensions and copying, and finally tuples and sets.
What a list is in Python
A list keeps its items in the order you give them and accesses them by index starting from zero. One list can hold values of different types, although in practice it usually stores data of one kind.
amounts = [250, 1200, 99]
print(amounts[0]) # 250 — the first item
print(amounts[-1]) # 99 — the last one
amounts[1] = 1300 # a list is mutable
print(len(amounts)) # 3 — the length of the list
The size of a list is returned by the len() function. Accessing a non-existent index gives IndexError: list index out of range.
Creating a list
empty = [] # an empty list
also_empty = list() # the same, via the list function
nums = [1, 2, 3]
chars = list("abc") # ['a', 'b', 'c']
digits = list(range(5)) # [0, 1, 2, 3, 4]
zeros = [0] * 4 # [0, 0, 0, 0]
The list() function turns any iterable object into a list: a string, a range, a set, the keys of a dictionary.
append and other list methods
The append method adds one item to the end of a list — the most common method in Python. It changes the list in place and returns None.
amounts = [250, 1200]
amounts.append(450) # [250, 1200, 450]
amounts.extend([10, 20]) # [250, 1200, 450, 10, 20]
amounts.insert(0, 5) # [5, 250, 1200, 450, 10, 20]
amounts.remove(1200) # remove the first value 1200
last = amounts.pop() # 20 — remove and return the last item
A common mistake: a.append([10, 20]) adds one item — a nested list, not two numbers. For several items you need extend.
| Method | What it does |
|---|---|
append(x) | add x to the end |
extend(iter) | add all items of a sequence |
insert(i, x) | insert x before index i |
remove(x) | remove the first occurrence of x (ValueError if absent) |
pop(i=-1) | remove and return the item at index i |
index(x) | index of the first occurrence |
count(x) | how many times x occurs |
sort() | sort in place |
reverse() | reverse in place |
copy() | shallow copy |
clear() | empty the list |
You can also remove an item by index, or a whole range, with the del statement: del a[0], del a[1:3]. Useful built-in functions for lists: len, sum, min, max, sorted, reversed, enumerate, zip.
Slicing in Python
A slice takes a part of a list using the pattern a[start:stop:step]: from start inclusive to stop exclusive, with step step. Any part can be omitted. A slice always returns a new list.
a = [0, 1, 2, 3, 4, 5]
print(a[1:4]) # [1, 2, 3]
print(a[:2]) # [0, 1] — the first two
print(a[-2:]) # [4, 5] — the last two
print(a[::2]) # [0, 2, 4] — every second item
print(a[::-1]) # [5, 4, 3, 2, 1, 0] — reversed
print(a[:]) # a copy of the whole list
Unlike an index, a slice beyond the list does not cause an error: a[10:20] simply returns []. You can assign to a slice and replace a piece of the list: a[1:3] = ["x", "y", "z"].
Slicing a string
Slices work the same way for any sequences, including strings and tuples:
s = "Python 3.15"
print(s[:6]) # Python
print(s[-4:]) # 3.15
print(s[::-1]) # 51.3 nohtyP
You cannot change a string with a slice — strings are immutable, and a slice creates a new string.
Sorting a list: sort and sorted
This is where beginners most often get confused. The sort method rearranges the items in the list itself and returns None. The sorted function does not touch the original list and returns a new sorted one.
amounts = [250, 1200, 99]
amounts.append(450)
print(sorted(amounts)) # [99, 250, 450, 1200] — a new copy
print(amounts) # [250, 1200, 99, 450] — the original is intact
result = amounts.sort() # sorts in place
print(result, amounts) # None [99, 250, 450, 1200]
Hence the classic "why do I get None" error: a = a.sort() overwrites the list with the value None. Write either a.sort() or a = sorted(a).
Key and reverse order
Both variants accept the key and reverse parameters. key is a function whose result is used to compare the items.
words = ["coffee", "Taxi", "subscription"]
print(sorted(words, key=len)) # ['coffee', 'Taxi', 'subscription']
print(sorted(words, key=str.lower)) # case-insensitive
print(sorted([3, 1, 2], reverse=True)) # [3, 2, 1]
expenses = [("Food", 650), ("Cinema", 120), ("Taxi", 300)]
expenses.sort(key=lambda e: e[1]) # by amount
Sorting in Python is stable: items with the same key keep their original order. Another difference is applicability: sorted accepts any sequence (a string, a dictionary, a set), while sort exists only for lists.
Reversing a list
Three ways with different behaviour:
a.reverse()— reverses in place, returnsNone;a[::-1]— a new reversed list;reversed(a)— a lazy iterator, convenient in a loop:for x in reversed(a):.
Iterating over a list
items = ["coffee", "metro", "cinema"]
for item in items:
print(item)
for i, item in enumerate(items, start=1):
print(i, item) # 1 coffee, 2 metro, 3 cinema
print("cinema" in items) # True — membership check
Do not remove items from the list you are looping over — some items will be skipped. Build a new list with a comprehension or iterate over a copy a[:].
List comprehensions
A list comprehension builds a new list in one line: an expression, a loop and an optional condition.
squares = [n * n for n in range(6)] # [0, 1, 4, 9, 16, 25]
big = [a for a in [250, 1200, 99] if a > 200] # [250, 1200]
names = [s.strip().title() for s in [" anna ", "oleg"]]
Comprehensions are usually faster and more readable than a loop with append. But if the logic does not fit into one clear line, an honest loop is better.
Joining, adding and subtracting lists
a = [1, 2, 3]
b = [3, 4]
print(a + b) # [1, 2, 3, 3, 4] — a new list
a += b # the same as a.extend(b)
print([*a, *b]) # unpacking into a new list
There is no list subtraction with the - operator. To remove from one list the items of another, use a comprehension: [x for x in a if x not in set(b)]. The intersection of lists is most easily found through sets: set(a) & set(b) (the order and duplicates are lost in the process).
Nested and two-dimensional lists
A list of lists is a simple way to store a table or a matrix:
matrix = [[1, 2, 3], [4, 5, 6]]
print(matrix[1][2]) # 6
grid = [[0] * 3 for _ in range(2)] # correct
bad = [[0] * 3] * 2 # a trap: two references to one list
bad[0][0] = 9
print(bad) # [[9, 0, 0], [9, 0, 0]]
Unpacking a list
first, second, third = [10, 20, 30]
head, *rest = [1, 2, 3, 4] # head=1, rest=[2, 3, 4]
print(*["a", "b"], sep=", ") # a, b — printing a list without brackets
If the number of variables does not match the length of the list, you get a ValueError — the asterisk comes to the rescue.
Copying a list
b = a does not copy the list: it attaches a second label to the same object, so changes made through b are visible in a. An independent copy is made explicitly: a.copy(), list(a) or a[:]. For nested data this is not enough — the inner lists remain shared, and you need copy.deepcopy(a).
import copy
a = [[1, 2], [3]]
b = a.copy()
b[0].append(99)
print(a) # [[1, 2, 99], [3]] — the nested list is shared
c = copy.deepcopy(a) # a fully independent copy
Tuples: an immutable list
A tuple (tuple) looks like a list, but once created it cannot be changed. This is an honest signal to the reader: you are looking at one record with fixed fields, not a growing collection. Tuples unpack easily, and functions use them to return several values.
expense = (250, "Coffee")
amount, item = expense
expense[0] = 300
# TypeError: 'tuple' object does not support item assignment
A tuple made of immutable values is hashable, so it can serve as a dictionary key. A one-item tuple is written with a comma: (5,).
Sets: unique values only
A set (set) stores only unique values and does not remember the order. It is the fastest way to remove duplicates and to check "is there such an item", and it also supports intersection, union and difference.
jan = {"Food", "Taxi", "Cinema"}
feb = {"Food", "Subscriptions"}
print(jan & feb) # {'Food'}
print(feb - jan) # {'Subscriptions'}
unique = list(dict.fromkeys([3, 1, 3, 2])) # [3, 1, 2] — no duplicates, order kept
empty = set() # {} would be an empty dict!
Which collection to choose
| Task | Collection |
|---|---|
| Order and changes | list |
| A fixed record | tuple |
| Lookup by key | dict |
| Uniqueness, "is it there" checks | set |
| Immutable settings | frozendict (Python 3.15) |
A check x in list goes through the items one by one, while x in set works almost instantly. If you check membership in a large list many times inside a loop, turn it into a set.
Summary
The Python list is an ordered mutable collection: append and extend add items, pop and remove delete them, slices a[start:stop:step] take parts, sort sorts in place and returns None, while sorted gives a new list. Make copies explicitly, use a tuple for fixed records and a set for unique values. Lists, tuples, dictionaries and sets are practised hands-on in our course "Python 3.15: from beginner to pro".
FAQ
How is a list different from an array in Python?
Python has no built-in array in the sense of other languages; its role is played by the list, which can hold values of different types. For compact numeric arrays there is the array module and the NumPy library.
How do I find the index of an item in a list?
The method a.index(x) returns the index of the first occurrence and raises ValueError if the item is absent. So it is worth checking x in a before the call.
How do I remove duplicates from a list while keeping the order?
Use list(dict.fromkeys(a)): a dictionary keeps keys unique and in insertion order. The variant list(set(a)) also removes duplicates, but does not keep the order.
How do I join a list of strings into one string?
With the string method join: ", ".join(["a", "b", "c"]) gives "a, b, c". All items must be strings; numbers are converted first with map(str, a).
Can a list hold items of different types?
Yes, a list can contain numbers, strings, other lists and any objects at the same time. But sorting such a list without a key parameter usually is not possible — comparing a number with a string raises TypeError.
This topic is covered in depth with practice in the course “Python 3.15: от новичка до профи”.
Go to course