Why does "x = x.append(…)" not work in a for loop?

Question:

I am trying to append objects to the end of a list repeatedly, like so:

list1 = []
n = 3
for i in range(0, n):
    list1 = list1.append([i])

But I get an error like: AttributeError: 'NoneType' object has no attribute 'append'. Is this because list1 starts off as an empty list? How do I fix this error?


This question is specifically about how to fix the problem and append to the list correctly. In the original code, the reported error occurs when using a loop because .append returns None the first time. For why None is returned (the underlying design decision), see Why do these list operations return None, rather than the resulting list?.

If you have an IndexError from trying to assign to an index just past the end of a list – that doesn’t work; you need the .append method instead. For more information, see Why does this iterative list-growing code give IndexError: list assignment index out of range? How can I repeatedly add elements to a list?.

If you want to append the same value multiple times, see Python: Append item to list N times.

Asked By: LostLin

||

Answers:

You don’t need the assignment operator. append returns None.

Answered By: Mikola

append returns None, so at the second iteration you are calling method append of NoneType. Just remove the assignment:

for i in range(0, n):
    list1.append([i])
Answered By: Yuri Stuken

Like Mikola said, append() returns a void, so every iteration you’re setting list1 to a nonetype because append is returning a nonetype. On the next iteration, list1 is null so you’re trying to call the append method of a null. Nulls don’t have methods, hence your error.

Answered By: John

Mikola has the right answer but a little more explanation. It will run the first time, but because append returns None, after the first iteration of the for loop, your assignment will cause list1 to equal None and therefore the error is thrown on the second iteration.

Answered By: Endophage

append actually changes the list. Also, it takes an item, not a list. Hence, all you need is

for i in range(n):
   list1.append(i)

(By the way, note that you can use range(n), in this case.)

I assume your actual use is more complicated, but you may be able to use a list comprehension, which is more pythonic for this:

list1 = [i for i in range(n)]

Or, in this case, in Python 2.x range(n) in fact creates the list that you want already, although in Python 3.x, you need list(range(n)).

Answered By: Andrew Jaffe

Note that you also can use insert in order to put number into the required position within list:

initList = [1,2,3,4,5]
initList.insert(2, 10) # insert(pos, val) => initList = [1,2,10,3,4,5]

And also note that in python you can always get a list length using method len()

Answered By: Artsiom Rudzenka

I personally prefer the + operator than append:

for i in range(0, n):

    list1 += [[i]]

But this is creating a new list every time, so might not be the best if performance is critical.

Answered By: Petar Ivanov

use my_list.append(…)
and do not use and other list to append as list are mutable.

Answered By: Ranjit
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.