Python List insert(): Add an Item at Any Position
The insert() method adds one item to a Python list at the position you choose. You hand it an index and a value, and the value cuts in right before whatever currently sits at that index:
steps = ["wash", "dry"]
steps.insert(1, "rinse")
print(steps) # Program output:
# ['wash', 'rinse', 'dry'] Nothing got overwritten. The "dry" item moved from index 1 to index 2 to make room. Inserting near the front of a long list takes more work because more items have to move.
Syntax and Basic Usage
items.insert(i, x)
# puts x before the item at index i - i (required integer): the position the new item should end up at. Negative indexes count back from the end, and an index outside the list is clamped to the nearest end.
- x (required, any type): the item to add, always as one item.
- Returns:
None. The list itself is what changes. - Raises:
TypeErrorwheniis not an integer or either argument is missing.
The index always comes first and the value second, so say it in your head the first few times you type it. Here are the front, the middle and the end of the same list:
letters = ["b", "c", "d"]
letters.insert(0, "a")
print(letters)
letters.insert(2, "x")
print(letters)
letters.insert(len(letters), "z")
print(letters) # Program output:
# ['a', 'b', 'c', 'd']
# ['a', 'b', 'x', 'c', 'd']
# ['a', 'b', 'x', 'c', 'd', 'z'] Inserting at len(letters) lands the item at the end, because there's nothing at that index for it to go in front of. That works, and it earns its place when the position comes from a calculation that sometimes lands on the end. When you always mean the end, use append(), because it says so plainly.
How Does Python insert() Use the Index?
Python insert(i, x) puts x before the item at index i. Index 0 adds to the front, and len(items) adds to the end. Negative indexes count back from the end.
Negative Indexes
A negative index counts from the end, just like it does when you read an item, and the new item still goes in before that position. So insert(-2, x) puts x before the second-to-last item:
letters = ["a", "b", "c"]
letters.insert(-2, "x")
print(letters) # Program output:
# ['a', 'x', 'b', 'c'] The same rule sends insert(-1, x) in before the last item. Use append() if the new item should come after the last item.
What Happens If Python insert() Gets an Out-of-Range Index?
Python insert() accepts an ordinary integer index outside the list without raising IndexError. An index past the end is treated as the end, and a negative index past the start is treated as the front:
letters = ["a", "b", "c"]
letters.insert(99, "end")
letters.insert(-99, "start")
print(letters) # Program output:
# ['start', 'a', 'b', 'c', 'end'] That's the opposite of pop(), which raises IndexError on a bad index. So an off-by-one index can land the item at an end without a peep. CPython still raises OverflowError if the integer is too large for its internal index type, as with insert(10**100, x).
For the loops and other language basics behind these examples, see our guide to learning Python.
Practical Examples
Adding a Header Row
Index 0 is probably the spot you'll reach for most often. It puts a heading in front of rows you've already collected, right before you print them or write them out:
rows = [["Ada", 36], ["Bo", 29]]
rows.insert(0, ["name", "age"])
for row in rows:
print(row) # Program output:
# ['name', 'age']
# ['Ada', 36]
# ['Bo', 29] Keeping a List Sorted
To drop a new value into an already sorted list and keep it sorted, you need to find the right index first. The standard library's bisect module finds that index and inserts for you:
import bisect
scores = [52, 67, 81, 94]
bisect.insort(scores, 75)
bisect.insort(scores, 40)
print(scores) # Program output:
# [40, 52, 67, 75, 81, 94] For a list that's already sorted, I'd recommend insort() over a search loop you write yourself, because it finds the spot with a binary search and inserts in the same call. The trade-off is that the list has to be sorted to begin with, or the position it picks won't mean anything.
Common Pitfalls and Debugging
insert(-1, x) Does Not Add to the End
Index -1 reads as "the last one", so you'd expect insert(-1, x) to add at the end. It inserts before the last item, and Python raises no error, so the bug only shows when you look at the order:
letters = ["a", "b", "c"]
letters.insert(-1, "x")
print(letters)
letters.append("y")
print(letters) # Program output:
# ['a', 'b', 'x', 'c']
# ['a', 'b', 'x', 'c', 'y'] When you mean the end, use append(), as the second call does.
TypeError: 'str' object cannot be interpreted as an integer
Swap the two arguments and Python tries to use your value as the index. CPython's error names the type of whatever landed in the index slot:
tasks = ["plan", "build"]
tasks.insert("ship", 2) # Program output:
# Traceback (most recent call last):
# ...
# TypeError: 'str' object cannot be interpreted as an integer Put the index first and the value second, as in tasks.insert(2, "ship"). A float index fails the same way, so insert(1.0, x) raises the same error with 'float' in it. Check what the computed position means before converting it: int() truncates toward zero, which can conceal a calculation error.
TypeError: insert expected 2 arguments
Pass only the value and insert() has no position to work with. CPython reports how many arguments it got:
tasks = ["plan", "build"]
tasks.insert("ship") # Program output:
# Traceback (most recent call last):
# ...
# TypeError: insert expected 2 arguments, got 1 If you meant the end of the list, you wanted append(). Otherwise, add the index in front of the value.
Inserting a List Nests It
Like append(), insert() adds exactly one item, so handing it a list puts the whole list in as a single nested item:
letters = ["a", "e"]
letters.insert(1, ["b", "c", "d"])
print(letters) # Program output:
# ['a', ['b', 'c', 'd'], 'e'] To splice several items in at one position, assign them to an empty slice. The slice letters[1:1] covers no items, so nothing gets replaced:
letters = ["a", "e"]
letters[1:1] = ["b", "c", "d"]
print(letters) # Program output:
# ['a', 'b', 'c', 'd', 'e'] Inserting at the Front of a Long List
Every insert has to slide the items after it one place along, so insert(0, x) moves every item already in the list, every time you call it. It's the Turnpike merge at rush hour: one car noses in up front, and every car behind it has to shuffle back.
On a short list you'll never notice. When a long list keeps growing at the front, the Python docs point you to collections.deque, whose appendleft() is built for that job:
from collections import deque
recent = deque(["page2", "page1"])
recent.appendleft("page3")
print(recent) # Program output:
# deque(['page3', 'page2', 'page1']) Don't swap a working list for a deque on a hunch, though. Make the switch when the list is big and the front inserts happen often.
insert() vs append() vs Slice Assignment
Three tools put new items into a list, and they split on where the items go and how many you can add per call.
| Tool | Where | How many |
|---|---|---|
insert(i, x) | Before index i | One item |
append(x) | The end | One item |
items[i:i] = xs | Before index i | Each item of xs |
Pick by where the items go and how many there are:
- For one item at the end,
append()is the clear choice. - For one item with a real position, like a header row at index 0, use
insert(). - When several items belong at the same spot, I'd recommend slice assignment over a loop of
insert()calls, because one assignment keeps them in their original order, while repeatedinsert(1, x)calls land them in reverse. The trade-off is readability, sinceitems[i:i] = xsis less obvious to a beginner than a method name.
For adding several items to the end, extend() is the usual choice, and we compare it with the other two in the Append, Extend, and Insert section of the Lists guide.
Choose the Right Position for Your New Item
Use insert(i, x) when an item has to go somewhere other than the end, and remember that it lands before the item at i. For the end of the list, reach for append() instead, and watch for an out-of-range index, because insert() won't complain about it. Run insert(-1, x) on a three-item list once and watch it land one spot early, and that rule will stay with you.
Frequently Asked Questions
Does Python insert() replace the item at the chosen index?
Python list.insert() adds a new item without replacing the item at that index. The existing item and everything after it move one position to the right. To replace an item instead, assign to its index, as in items[2] = x.
Why does Python insert() not raise IndexError?
Python list.insert() moves an out-of-range position to the nearest end of the list instead of raising IndexError. This applies to integers that fit the interpreter's index type; extremely large integers can raise OverflowError in CPython.
How do you insert at the end of a Python list?
To add one item to the end of a Python list, use items.append(x). The call items.insert(len(items), x) also works. On a nonempty list, items.insert(-1, x) puts the new item before the last item instead.
Can Python insert() add more than one item?
Python list.insert() adds exactly one item per call. Passing a list inserts it as one nested item. To insert several items at one position, assign to an empty slice, as in items[1:1] = ["b", "c"].
What does Python insert() return?
Python list.insert() returns None and changes the list in place. Writing items = items.insert(0, x) replaces your list with None, so call insert() on its own line.
Is Python insert() slower than append()?
Inserting near the front of a Python list takes more work than appending because insert() must shift the later items. Inserting at the end does not require that shift. Use append() when you always want to add at the end.
Does Python insert() work on strings or tuples?
Python strings and tuples have no insert() method because they cannot change in place. Calling insert() on either raises AttributeError. Build a new string with slicing and +, or convert the sequence to a list before inserting.
Next Steps
- Python Dictionaries - storing values under names when position does not matter.
Sources
-
[1]
Data Structures: More on Lists(docs.python.org)
-
[2]
Mutable Sequence Types(docs.python.org)
-
[3]
bisect: Array bisection algorithm(docs.python.org)
-
[4]
collections: deque objects(docs.python.org)
Read Next
The append() method adds one item to the end of a list and returns None. Syntax, what happens when you append a list, the AttributeError and TypeError it leads to, and how it compares with extend() and +=.
A Python list keeps items in the order you put them and lets you change that order later. How to create one, index and slice it, add and remove items, copy it safely, and recognize the jobs a list is wrong for.
The remove() method deletes the first matching value and pop() deletes by position and returns the item. Syntax, return values, the ValueError and IndexError each raises, and how both compare with del and clear().