Before you can do anything useful with a Python list, you need to know how to create one and how to reach the items stored inside it. These two skills, creation and access, are the foundation that every other list operation builds on. You cannot add to a list that does not exist yet, and you cannot modify an item you cannot reach. This article covers every common way to create a list and every way to pull data out of one, from single-item indexing to multi-dimensional slicing on nested structures.
If you have already read the overview of working with Python lists, you know that a list stores an ordered sequence of references to objects. The creation syntax you choose depends on where your data comes from and how much of it there is. A short, fixed list of values is easiest to write with square brackets. A list built from some other data source, a file, a range of numbers, a string of characters, is easier to create with the list constructor. A list whose elements follow a pattern is cleanest to express with a list comprehension.
Creating lists with square brackets
The most direct way to create a list is to write comma-separated values between a pair of square brackets. This is called a list literal, and it is the syntax you will use most often when you know the exact items ahead of time. The brackets themselves are the list constructor. There is no special keyword and no type declaration needed.
primes = [2, 3, 5, 7, 11]
names = ["Alice", "Bob", "Charlie"]
empty = []An empty pair of brackets creates an empty list, which is the starting point for programs that build a list incrementally inside a loop. A list literal can span multiple lines when the items are long or when you want to make each item visually distinct. Python ignores the line breaks inside the brackets. The trailing comma after the last item is optional but recommended because it makes version control diffs cleaner when you add another item later.
Creating lists with the list constructor
The built-in list function turns any iterable into a list. Pass it a string, and you get a list of individual characters. Pass it a range, and you get a list of numbers. Pass it a tuple, and you get a list with the same items in the same order. This is the preferred approach when your starting data is not already in list form.
chars = list("Python")
nums = list(range(10))
from_tuple = list((1, 2, 3))The list constructor also accepts no arguments, in which case it returns an empty list. This is functionally identical to writing an empty bracket pair, though the literal form is more common in Python code. Use the constructor when you are converting from another type; use the literal when you are starting from scratch.
Creating lists with comprehensions
A list comprehension builds a new list by evaluating an expression for every item in an existing iterable, optionally filtering with an if clause. Comprehensions are a distinctive Python feature that replaces the pattern of creating an empty list, looping, and appending, all in a single readable line.
squares = [x ** 2 for x in range(10)]
evens = [x for x in range(20) if x % 2 == 0]The comprehension reads almost like English: give me x squared for each x in the range zero through nine. You can include multiple for clauses to flatten nested structures and multiple if clauses to filter on several conditions. The dedicated article on list comprehensions in Python later in this section covers every variation. For now, recognize that comprehensions are a concise way to create a list when each element is a transformation or a filtered selection from another data source.
Accessing items by index
Once you have a list, you reach its items by writing the index inside square brackets after the list name. Python uses zero-based indexing, so the first item lives at position 0, not position 1. This is the same indexing convention used by strings, tuples, and every other sequence type in the language.
colors = ["red", "green", "blue"]
colors[0] # "red"
colors[1] # "green"
colors[2] # "blue"Negative indices let you count from the end of the list. The last item is always at index -1 regardless of the list's length. The second-to-last is at index -2, and so on. This is especially useful when you want the most recent item added to a list but do not want to calculate an index from the length every time. If you provide an index that does not exist, either because it is larger than the last valid index or because the list is empty, Python raises an IndexError.
Slicing lists
A slice extracts a contiguous portion of a list and returns it as a new list. The slice syntax uses a colon between the start and stop indices inside square brackets, and it follows the same half-open convention as the range function: the start index is included, and the stop index is excluded. When you omit the start index, the slice begins at the first element. When you omit the stop index, the slice runs to the end. Omitting both creates a shallow copy of the entire list.
A slice can also include a step value after a second colon. The step controls how many positions to advance between included items. A step of 2 takes every other element, and a negative step traverses the list backward. The reverse slice with a step of -1 is the idiomatic way to get a reversed copy of a list without modifying the original.
Accessing nested lists
A list can contain other lists, and those inner lists can contain still more lists, creating a nested structure. Accessing an element inside a nested list requires chaining index operations: the first index selects the inner list, and the second index selects the element inside that inner list. Each pair of brackets drills one level deeper into the structure. You can combine indexing and slicing on nested lists, though readability suffers if the expression gets too long. When you find yourself writing three or more levels of brackets, consider whether a dictionary, a class, or a NumPy array would express the data structure more clearly. The article on nested lists in Python covers multi-dimensional list patterns in depth, including how to create grids, how to iterate over nested structures, and the common pitfalls that arise when copying nested lists.
With creation and access covered, the next step is learning to modify Python lists by adding, removing, and rearranging their contents.
Rune AI
Key Insights
- Create lists with square brackets, the list constructor, or list comprehensions.
- Access individual items with zero-based indexing: my_list[0] is the first item.
- Use negative indices to count from the end: my_list[-1] is the last item.
- Slice sublists with the colon operator: my_list[start:stop:step].
- Nested lists are accessed with multiple index operations chained together.
Frequently Asked Questions
What is the difference between append and the list constructor?
What happens if I use an index that is too large?
Can I access list items from the end without knowing the length?
Conclusion
Creating and accessing lists are the two operations you will perform more than any other when working with Python collections. Mastering square-bracket syntax, zero-based indexing, slicing with start, stop, and step, and negative indices gives you the foundation for every list technique that follows.
More in this topic
Nested Lists in Python
Learn how to create, access, and modify nested lists in Python. Build grids and matrices, and understand how shallow copies affect multi-dimensional data.
List Comprehensions in Python
Master Python list comprehensions to create, filter, and transform lists in a single line. Learn the syntax, common patterns, and when to use a regular loop instead.
Copy Python Lists
Learn how to copy Python lists using slicing, the copy method, the list constructor, and the copy module. Understand shallow vs deep copies.