Python Lists
Learn how to create, access, and manipulate lists in Python.
Lists
Lists are used to store multiple items in a single variable.
Lists are one of 4 built-in data types in Python used to store collections of data, the other 3 are Tuple, Set, and Dictionary, all with different qualities and usage.
Lists are created using square brackets:
Example
thislist = ["apple", "banana", "cherry"]
print(thislist)List Items
List items are ordered, changeable, and allow duplicate values.
List items are indexed, the first item has index [0], the second item has index [1] etc.
Ordered
When we say that lists are ordered, it means that the items have a defined order, and that order will not change.
If you add new items to a list, the new items will be placed at the end of the list.
Changeable
The list is changeable, meaning that we can change, add, and remove items in a list after it has been created.
Allow Duplicates
Since lists are indexed, lists can have items with the same value:
Example
thislist = ["apple", "banana", "cherry", "apple", "cherry"]
print(thislist)List Length
To determine how many items a list has, use the len() function:
Example
thislist = ["apple", "banana", "cherry"]
print(len(thislist))List Items - Data Types
List items can be of any data type:
Example
list1 = ["apple", "banana", "cherry"]
list2 = [1, 5, 7, 9, 3]
list3 = [True, False, False]A list can contain different data types:
Example
list1 = ["abc", 34, True, 40, "male"]type()
From Python's perspective, lists are defined as objects with the data type 'list':
Example
mylist = ["apple", "banana", "cherry"]
print(type(mylist))The list() Constructor
It is also possible to use the list() constructor when creating a new list.
Example
thislist = list(("apple", "banana", "cherry")) # note the double round-brackets
print(thislist)Access List Items
List items are indexed and you can access them by referring to the index number:
Example
thislist = ["apple", "banana", "cherry"]
print(thislist[1])Negative Indexing
Negative indexing means start from the end
-1 refers to the last item, -2 refers to the second last item etc.
Example
thislist = ["apple", "banana", "cherry"]
print(thislist[-1])Range of Indexes
You can specify a range of indexes by specifying where to start and where to end the range.
When specifying a range, the return value will be a new list with the specified items.
Example
thislist = ["apple", "banana", "cherry", "orange", "kiwi", "melon", "mango"]
print(thislist[2:5])Change List Items
To change the value of a specific item, refer to the index number:
Example
thislist = ["apple", "banana", "cherry"]
thislist[1] = "blackcurrant"
print(thislist)Change a Range of Item Values
To change the value of items within a specific range, define a list with the new values, and refer to the range of index numbers where you want to insert the new values:
Example
thislist = ["apple", "banana", "cherry", "orange", "kiwi", "mango"]
thislist[1:3] = ["blackcurrant", "watermelon"]
print(thislist)Add List Items
Append Items
To add an item to the end of the list, use the append() method:
Example
thislist = ["apple", "banana", "cherry"]
thislist.append("orange")
print(thislist)Insert Items
To insert a list item at a specified index, use the insert() method.
Example
thislist = ["apple", "banana", "cherry"]
thislist.insert(1, "orange")
print(thislist)Extend List
To append elements from another list to the current list, use the extend() method.
Example
thislist = ["apple", "banana", "cherry"]
tropical = ["mango", "pineapple", "papaya"]
thislist.extend(tropical)
print(thislist)Remove List Items
Remove Specified Item
The remove() method removes the specified item.
Example
thislist = ["apple", "banana", "cherry"]
thislist.remove("banana")
print(thislist)Remove Specified Index
The pop() method removes the specified index.
Example
thislist = ["apple", "banana", "cherry"]
thislist.pop(1)
print(thislist)If you do not specify the index, the pop() method removes the last item.
Example
thislist = ["apple", "banana", "cherry"]
thislist.pop()
print(thislist)The del keyword
The del keyword also removes the specified index:
Example
thislist = ["apple", "banana", "cherry"]
del thislist[0]
print(thislist)The del keyword can also delete the list completely.
Example
thislist = ["apple", "banana", "cherry"]
del thislistClear the List
The clear() method empties the list. The list still remains, but it has no content.
Example
thislist = ["apple", "banana", "cherry"]
thislist.clear()
print(thislist)List Comprehensions
A comprehension builds a list in one readable line — the Pythonic replacement for many for + append loops.
squares = [x ** 2 for x in range(5)] # [0, 1, 4, 9, 16]
evens = [x for x in range(10) if x % 2 == 0] # [0, 2, 4, 6, 8]
upper = [w.upper() for w in ["a", "b"]] # ['A', 'B']Common Methods
| Method | Does | Time |
|---|---|---|
append(x) | Add to end | O(1) |
insert(i, x) | Insert at index | O(n) |
pop() / pop(i) | Remove & return | O(1) / O(n) |
remove(x) | Delete first match | O(n) |
sort() | Sort in place | O(n log n) |
reverse() | Reverse in place | O(n) |
sort() returns None (it sorts in place). Use sorted(mylist) when you want a new sorted list and keep the original.
Copying a List
a = [1, 2, 3]
b = a # alias -> changes to b affect a
c = a[:] # shallow copy (or a.copy())
c.append(4)
print(a) # [1, 2, 3] -> unaffectedTry It Yourself
Exercise 1: Build a list of the cubes of 1–5 using a comprehension.
Show solution
print([x ** 3 for x in range(1, 6)]) # [1, 8, 27, 64, 125]Exercise 2: From [3, 1, 2] produce a NEW sorted list without changing the original.
Show solution
nums = [3, 1, 2]
print(sorted(nums)) # [1, 2, 3]
print(nums) # [3, 1, 2] -> unchangedExercise 3: Remove duplicates from [1, 2, 2, 3, 3, 3] while keeping it a list.
Show solution
print(list(set([1, 2, 2, 3, 3, 3]))) # [1, 2, 3] (order may vary)Key Takeaways
- Lists are ordered, mutable, and allow duplicates.
- Comprehensions replace many loops in one clear line.
sort()mutates and returnsNone;sorted()returns a new list.- Copy with
[:]or.copy()to avoid aliasing.
📘 Real-World Deep Dive
Lists are Python's default ordered, mutable, heterogeneous collection. You reach for them so often that list-fluency (iteration, comprehensions, slicing, mutating methods) is the single biggest speed-up on daily coding tasks.
Real-Life Scenario
A shopping cart with line items — constant mutation (add/remove/update), ordering preserved, and frequent iteration to compute the total.
Real-Life Example
from dataclasses import dataclass, field
from typing import Iterable
@dataclass
class LineItem:
sku: str
qty: int
price: float
@dataclass
class Cart:
items: list[LineItem] = field(default_factory=list)
currency: str = "USD"
def add(self, sku: str, qty: int, price: float) -> None:
existing = next((it for it in self.items if it.sku == sku), None)
if existing:
existing.qty += qty
else:
self.items.append(LineItem(sku, qty, price))
def remove(self, sku: str) -> None:
self.items[:] = [it for it in self.items if it.sku != sku]
def subtotal(self, tax_rate: float = 0.0) -> float:
raw = sum(it.qty * it.price for it in self.items)
return round(raw * (1 + tax_rate), 2)
cart = Cart()
for sku, qty, price in [("SKU-1", 2, 9.99), ("SKU-2", 1, 24.50), ("SKU-1", 1, 9.99)]:
cart.add(sku, qty, price)
cart.remove("SKU-2")
print("lines :", len(cart.items))
print("subtotal :", cart.subtotal(tax_rate=0.0875))
print("most-expensive:", max(cart.items, key=lambda it: it.price * it.qty))Expected Output
lines : 1
subtotal : 32.83
most-expensive: LineItem(sku='SKU-1', qty=3, price=9.99)Common mistakes
- Mutating a list while iterating it skips or repeats elements — iterate over a copy (
for x in xs[:]) or build a new list. - Using
lst = lst + [...]creates a brand-new list every call (O(n)); uselst.appendorlst.extendfor hot loops. - A list passed to a function keeps living if the function mutates it — defensively copy with
list(xs)or use a tuple.
🚀 Performance & Best Practices
collections.dequebeatslistfor left-end pop/append (O(1) vs O(n)).- Search inside a list is O(n); wrap the membership check in a
setfor big collections. "".join(parts)is far faster than+=for building long strings from a list of fragments.
🧪 Try It Yourself
- Add a
discount_codes: dict[str, float]field toCartand apply the largest one that applies. - Replace
removewith a "soft delete" that hides items behind a flag and writes them toremoved_history. - Profile
subtotal()with 1 M line items and time list-sum vs.math.fsum.