Creating and accessing lists
A list is an ordered, changeable collection that can hold any mix of types. It is the workhorse data structure of Python.
scores = [88, 92, 79, 95]
mixed = [1, "two", 3.0, [4, 5]]
empty = []
print(scores[0], scores[-1]) # first, last
print(scores[1:3]) # slice -> [92, 79]
print(len(scores))
print(95 in scores)
print(mixed[3][1]) # nested accessIndexing past the end raises IndexError; slicing past the end just returns fewer items.
Adding and removing items
todo = ["write", "test"]
todo.append("ship") # add to end
todo.insert(0, "plan") # add at position
todo.extend(["celebrate", "rest"]) # add several
print(todo)
todo.remove("test") # by value (first match)
last = todo.pop() # remove & return last
first = todo.pop(0) # remove & return by index
del todo[0] # delete by index
print(todo, last, first)
todo.clear()
print(todo)append adds one item; extend adds each item of another iterable. todo.append([1, 2]) would add the whole list as a single nested element.
Sorting and reversing
nums = [5, 2, 9, 1]
nums.sort() # in place, returns None
print(nums)
nums.sort(reverse=True)
print(nums)
words = ["pear", "Apple", "fig"]
print(sorted(words)) # new list, case-sensitive
print(sorted(words, key=str.lower)) # case-insensitive
print(sorted(words, key=len)) # by length
words.reverse()
print(words)The classic bug: result = nums.sort() leaves result as None. Use sorted() when you want a value back.
Useful built-ins with lists
data = [4, 8, 15, 16, 23, 42]
print(sum(data), min(data), max(data))
print(sum(data) / len(data)) # average
print(data.index(15), data.count(8))
print(any(x > 40 for x in data), all(x > 0 for x in data))
print(list(reversed(data)))Copying lists
a = [1, 2, 3]
b = a # alias, same object
c = a[:] # shallow copy
d = a.copy() # shallow copy
b.append(4)
print(a, c, d)
import copy
nested = [[1, 2], [3]]
deep = copy.deepcopy(nested)
nested[0].append(99)
print(nested, deep)Shallow copies duplicate the outer list only; inner lists are still shared. Use deepcopy when a list contains lists.
List comprehensions
A comprehension builds a list in one readable line. It replaces the append-in-a-loop pattern:
squares = [n * n for n in range(1, 6)]
evens = [n for n in range(20) if n % 2 == 0]
shout = [w.upper() for w in ["hi", "there"]]
pairs = [(x, y) for x in range(2) for y in range(2)]
labels = ["even" if n % 2 == 0 else "odd" for n in range(4)]
print(squares)
print(evens)
print(shout, pairs)
print(labels)Read it as "collect expression for each item in iterable, if condition". If a comprehension needs more than one line to understand, write a loop instead.
Tuples: the immutable cousin
point = (3, 4)
x, y = point # unpacking
print(x, y, point[0])
single = (5,) # note the comma
print(type(single))
# point[0] = 9 -> TypeError: tuples cannot changeUse a tuple for fixed groupings (coordinates, RGB colours, function return values) and a list for collections that grow and shrink. Tuples can also be dictionary keys; lists cannot. Speaking of which: dictionaries and sets are next.
Frequently asked questions
What is the difference between a list and a tuple?
Lists are mutable (you can add, remove and change items); tuples are immutable. Tuples are slightly faster, can be dictionary keys, and signal that the data is a fixed record.
How do I remove duplicates from a list?
list(set(items)) removes duplicates but loses order. To keep order use list(dict.fromkeys(items)).
Why does my_list.sort() return None?
sort() sorts the list in place and deliberately returns None so you do not confuse it with sorted(), which returns a new list.
How do I copy a list in Python?
Use new = old.copy() or new = old[:]. Plain new = old only creates a second name for the same list. For nested lists use copy.deepcopy().