FULL PYTHON FIX · 6 MIN READ
Why Does Python list.append() Return None?
The item was added, yet the variable assigned from append() contains None. See exactly which object changed and choose the right pattern for your program.
Video guide: Why Does Python list.append() Return None?
The preview is stored on this site. YouTube loads only when you press Play. Watch on YouTube
Jump to a chapter
Read the video transcript
Select a timestamp to watch that moment on YouTube.
- 00:00
Here is a tiny Python program that surprises many new developers. We start with a list containing Ada, append Mina, and save the result of that call in a variable named result. What will print when we display result, and what will print when we display names? Pause and make two separate predictions. It feels natural to expect result to contain the updated list, because a function often hands back the answer it computed. But Python list methods have a different convention for operations that change the list itself. In this lesson we will run the code, inspect both values, repair the assignment, and test what happens when another variable points to the same list.
- 00:43
We will also compare append with making a new list, because both can produce a list with one additional item but they have different effects on the original. Understanding that difference prevents a whole family of bugs in functions and loops. The key debugging habit is to inspect the object that might have changed and the value the method returned. Do not assume they are the same thing just because the method name sounds like a calculation. Let us run the original program exactly as written. The first printed line is None. The second is the list with both Ada and Mina. Those two observations matter together. The append call succeeded: the item is present in names.
- 01:26
The assignment to result also succeeded: it stored the value that append returned, which is None. There is no exception yet. The bug becomes visible if later code tries to treat result as a list. For example, iterating over result or asking for its length would fail because None is not a list. A more dangerous variation assigns the returned value back to names. Python evaluates the right side first, so the list is modified, then the name names is rebound to None. After that line, names no longer gives us access to the list. If we only look at the final None, we might wrongly think the append did not happen.
- 02:07
Running a two-line diagnostic is a better approach than guessing. Keep the original list variable and the return value in separate names until you know where the data went. The printed output provides a precise explanation: one object changed in place, while a different variable holds the method's return value. Now inspect the types and contents explicitly. We start over with a one-item list, call append, then print the returned type name and the length of names. Python reports NoneType for the returned value and a length of two for the changed list. The Python documentation describes list append as adding an item to the end of the list.
- 02:49
It is an in-place operation, which means it changes this list object rather than building and returning another one. This convention also appears with other methods that mutate a list, such as extend, insert, reverse, and sort. The exact method is less important than the habit: check whether it changes an object and what it returns before assigning its result. Why would a language design choose None here? It makes a side effect easier to notice. Code that expects an independent list cannot silently receive one. We can also inspect identity. If alias points at the same list, calling append through names makes the new item visible through alias too.
- 03:31
That is not a copy, and it is not a second append. Both variables point to one mutable object. Once you see this, the earlier output is no longer mysterious. The result variable answers what the method returned; names answers what happened to the list. The smallest correction is to call names dot append with Mina on its own line. On the next line, print names. When we run it, the list contains Ada and Mina. We did not change the data type or add a special conversion; we simply stopped assigning the method's None return value. This is the right pattern when changing the existing list is the intended behavior.
- 04:12
But sometimes a function should leave its input untouched. Suppose original must remain the one-item list while updated gets both names. In that case, use original plus a one-item list, or another explicit copy-and-add approach. Run both print statements and confirm that original still contains only Ada while updated contains Ada and Mina. That new-list operation costs memory for the new list, whereas append modifies the one already present. Neither is universally better; the choice depends on the function's contract. It is especially important when multiple parts of a program share a list reference.
- 04:53
Mutating a shared list changes what all its aliases see. Creating a new list does not change the original list. The two approaches can print the same final values in one example while producing different behavior elsewhere, so verify both the desired result and the intended side effect. We will test one more variation instead of stopping after a successful run. Start with an empty list and assign alias to that same object. Append the number seven, then print items, print whether alias is items, and print alias. The output shows the seven and True: both names observe the one modified list. Now compare append and extend with the values two and three.
- 05:36
Appending the list as one item creates a nested list. Extending with that list adds two separate items. This is another common source of unexpected output, and it reinforces the same question: what exact object is changed by this call? For your exercise, make a task list with read, add practice and review with two append calls, and print the length. Then create a separate list with publish while leaving the first list unchanged. Predict every output before running. If you see None where a list is expected, trace the assignment on the line that called a mutating method. The matching guide on PythonLessonLab includes runnable examples, the exact output, and a practice prompt.
- 06:21
The related Lists lesson gives you a browser console and a checked task. Use those to test the rule yourself, then try explaining it in one sentence: append changes the existing list and returns None.
The item appears, but the result is None
Suppose you have a list of names and want to add another name. It is tempting to assign the result of append() because many functions return their result. Run the program and predict both printed lines before looking at the output. The second line shows that the list really did grow. The first line shows that the expression names.append('Mina') did not return the updated list.
This is a logic mistake rather than an exception at the append call. It becomes an exception later if you try to index or iterate over result, because result is None. Keep the original list and the value returned by the method separate while diagnosing the problem.
names = ['Ada']
result = names.append('Mina')
print(result)
print(names)None
['Ada', 'Mina']Inspect the object and the method result
append() changes the existing list in place and returns None. That design makes the side effect explicit: the method's useful result is the changed object, not a separate value. Print both the return type and the list contents. If the list now contains the new item, append succeeded; assigning its return value was the only wrong step.
A particularly damaging form is names = names.append('Mina'). Python evaluates the right-hand side first, modifies the list, then assigns None back to names. You have lost the variable that referred to the list. The list object may still exist if another variable referred to it, but the name names no longer points there.
names = ['Ada']
returned = names.append('Mina')
print(type(returned).__name__)
print(len(names), names)NoneType
2 ['Ada', 'Mina']names = ['Ada']
names = names.append('Mina')
print(names)NoneCall append() on its own line
When you want to update the existing list, call append() without assigning its return value. Then use the original list variable. This is the smallest repair: delete only the assignment on the append line. It also makes the program easier to read, because the operation and the later use of the list are visibly separate.
Sometimes you need a new list while preserving the original. In that case, concatenation or unpacking creates a different list. Choose that deliberately rather than expecting append() to copy. Be aware that copying a list this way is shallow: nested mutable objects inside it are still shared. For simple names or numbers, that distinction usually does not matter.
names = ['Ada']
names.append('Mina')
print(names)['Ada', 'Mina']original = ['Ada']
updated = original + ['Mina']
print(original)
print(updated)['Ada']
['Ada', 'Mina']Test the empty case and the object identity
A single successful example can hide a mistaken assumption about copying. Test an empty list and inspect whether the object before and after append is the same. The is comparison below is True because append changed the original list. If other code holds an alias to that list, it will observe the added item too.
For a fresh list, original + [item] leaves the old list untouched. This matters when a function should not modify its caller's input. Decide which contract the function should have, write a small test for it, and then select append or a copy. Also remember that append adds one object; extend adds items from an iterable. Appending a list creates a nested list, which is correct only when that nesting is intended.
items = []
alias = items
items.append(7)
print(items)
print(alias is items, alias)[7]
True [7]first = [1]
first.append([2, 3])
second = [1]
second.extend([2, 3])
print(first)
print(second)[1, [2, 3]]
[1, 2, 3]- After items.append(7), items contains 7 and the method result is None.
- An alias to items sees the same modification.
- Use a new-list expression when the original must remain unchanged.
Practice the fix
Start with tasks = ['read']. Add 'practice' and 'review' so tasks has three strings. Print tasks and its length. Then create a separate extended list with 'publish' while leaving tasks unchanged. Verify both lists by printing them.
Need a hint?
Call tasks.append(...) on its own line twice. For the separate list, use extended = tasks + ['publish']. Do not assign the return value of append().
Python console
Ready to runEdit the code and run it in your browser. Examples above can be loaded with Try this example.
Does your code use input()? Add one value per line
Your output appears here.
Write your solution, then select Check practice.
Key takeaways
- list.append() modifies the existing list and returns None.
- Assigning names = names.append(item) replaces the variable with None.
- Call append() on its own line, then use the original list.
- Create a new list explicitly when the caller's list must remain unchanged.