86

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?

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
LostLin
  • 7,762
  • 12
  • 51
  • 73
  • 46
    No -1 please. The fact that append() returns None can trick beginers. The question is genuine. – Bite code Jun 14 '11 at 07:26
  • Rather than using a loop to `.append` each time, it is simpler and more efficient to just `.extend` with all the values: `list1.extend(range(n))` - no loop needed. However, the question isn't really about the loop, that was just what turned the problem of returning `None` into an actual exception. See also https://stackoverflow.com/questions/6039605 (only tangentially related). – Karl Knechtel Aug 03 '22 at 23:43
  • I didn't mark this as a duplicate because the underlying task - repeatedly appending to a list - merits consideration on its own. However, most questions about `.append` will be better closed as a duplicate of the other canonical. – Karl Knechtel Sep 14 '22 at 12:29
  • There are better identified canonicals now (part of the material is covered by something I ended up having to write myself), so this is closed now. There are two separate issues here, which makes it not properly focused as a canonical: the debugging issue of `.append` in a loop (which is a special case of `.append` returning None), and the how-to of building a list iteratively. – Karl Knechtel Mar 08 '23 at 18:29

8 Answers8

75

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)).

Andrew Jaffe
  • 26,554
  • 4
  • 50
  • 59
20

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

Mikola
  • 9,176
  • 2
  • 34
  • 41
6

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])
Yuri Stuken
  • 12,820
  • 1
  • 26
  • 23
3

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.

Endophage
  • 21,038
  • 13
  • 59
  • 90
2

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.

Petar Ivanov
  • 91,536
  • 11
  • 82
  • 95
1

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()

Artsiom Rudzenka
  • 27,895
  • 4
  • 34
  • 52
0

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.

John
  • 15,418
  • 12
  • 44
  • 65
-3

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

Ranjit
  • 17
  • 6
  • 2
    This answer is hard to understand (I'm not sure what you mean by the second part, for example) and either repeats information from the existing answers (from 2014) or (if taken literally) is flat out wrong (OP's code contains no `my_list` variable). – melpomene Jul 19 '17 at 18:20