879

How do I create an empty list that can hold 10 elements?

After that, I want to assign values in that list. For example:

xs = list()
for i in range(0, 9):
   xs[i] = i

However, that gives IndexError: list assignment index out of range. Why?


Editor's note:

In Python, lists do not have a set capacity, but it is not possible to assign to elements that aren't already present. Answers here show code that creates a list with 10 "dummy" elements to replace later. However, most beginners encountering this problem really just want to build a list by adding elements to it. That should be done using the .append method, although there will often be problem-specific ways to create the list more directly. Please 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? for details.

Pikamander2
  • 7,332
  • 3
  • 48
  • 69
Ronaldinho Learn Coding
  • 13,254
  • 24
  • 83
  • 110
  • 13
    An “empty list” (`[]`) by definition has zero elements. What you apparently want is a list of falsy values like `None`, `0`, or `''`. – dan04 Nov 29 '16 at 22:36

18 Answers18

1308

You cannot assign to a list like xs[i] = value, unless the list already is initialized with at least i+1 elements (because the first index is 0). Instead, use xs.append(value) to add elements to the end of the list. (Though you could use the assignment notation if you were using a dictionary instead of a list.)

Creating an empty list:

>>> xs = [None] * 10
>>> xs
[None, None, None, None, None, None, None, None, None, None]

Assigning a value to an existing element of the above list:

>>> xs[1] = 5
>>> xs
[None, 5, None, None, None, None, None, None, None, None]

Keep in mind that something like xs[15] = 5 would still fail, as our list has only 10 elements.

range(x) creates a list from [0, 1, 2, ... x-1]

# 2.X only. Use list(range(10)) in 3.X.
>>> xs = range(10)
>>> xs
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Using a function to create a list:

>>> def display():
...     xs = []
...     for i in range(9): # This is just to tell you how to create a list.
...         xs.append(i)
...     return xs
... 
>>> print display()
[0, 1, 2, 3, 4, 5, 6, 7, 8]

List comprehension (Using the squares because for range you don't need to do all this, you can just return range(0,9) ):

>>> def display():
...     return [x**2 for x in range(9)]
... 
>>> print display()
[0, 1, 4, 9, 16, 25, 36, 49, 64]
Dean MacGregor
  • 11,847
  • 9
  • 34
  • 72
varunl
  • 19,499
  • 5
  • 29
  • 47
  • 20
    What do you mean by "You cannot assign to a list like lst[i] = something" - of course you can! What you can't do is to assign to a non-existent element beyond the current list length – Sergey Apr 23 '18 at 23:28
  • 18
    "unless the list already is initialized with at least i+1 elements".... – MrR Oct 30 '18 at 13:30
  • 9
    you can do this: `a = [0 for _ in range(10)]` – Kamiar Dec 19 '18 at 21:55
  • 1
    This wont work if you're trying to create an matrix/2D List of a fixed size. Refer to James L.'s and user2233706's answers. – aklingam May 27 '21 at 08:44
  • Why does python not have a professional function to initialise an empty n dimensional list? – user2585501 Oct 13 '21 at 02:01
  • What is the time complexity of l = [None] * 10 this ? – Parikshit Chalke Dec 06 '21 at 15:35
  • 13
    **CAUTION** this creates a list of *pointers*. Doing it with any non primitive object will create a list of pointers *to the same object*. This means you should know what you're doing if you replace None with something else. – Gulzar Jan 29 '22 at 18:39
221

Try this instead:

lst = [None] * 10

The above will create a list of size 10, where each position is initialized to None. After that, you can add elements to it:

lst = [None] * 10
for i in range(10):
    lst[i] = i

Admittedly, that's not the Pythonic way to do things. Better do this:

lst = []
for i in range(10):
    lst.append(i)

Or even simpler, in Python 2.x you can do this to initialize a list with values from 0 to 9:

lst = range(10)

And in Python 3.x:

lst = list(range(10))
Óscar López
  • 232,561
  • 37
  • 312
  • 386
  • 9
    The other great thing about this is that you can initialise a list with default values. `lst = [''] * 10` or `lst = [0] * 10` – Anthony Manning-Franklin Sep 14 '16 at 03:47
  • 3
    A variant on the comprehension example. If all elements in the array need to be empty at initialization, use: `arr = [None for _ in range(10)]`. – Deacon Mar 31 '17 at 18:23
  • This format is `lst = list(range(10))` is looked nice. Like the same length in Java `int [] arr = new int[10]` – Zhou Haibo Jul 01 '20 at 14:54
  • Why is that first example not the "pythonic" way to do things? – twistedpixel Nov 16 '21 at 20:31
  • 1
    @twistedpixel because you're not supposed to use the index to access the elements in a for loop _unless you really need it_. A simple `for element in theList` is preferred for the majority of cases. – Óscar López Nov 16 '21 at 20:32
  • CAUTION this creates a list of pointers. Doing it with any non primitive object will create a list of pointers to the same object. This means you should know what you're doing if you replace None with something else. – Gulzar Jan 29 '22 at 18:41
  • @Deacon why would you prefer that over `arr = [None] * 10`? – Mark Ransom Oct 15 '22 at 02:27
  • @MarkRansom - It's over 5 years ago. No clue why I chose that approach! – Deacon Oct 16 '22 at 03:25
153

varunl's currently accepted answer

 >>> l = [None] * 10
 >>> l
 [None, None, None, None, None, None, None, None, None, None]

Works well for non-reference types like numbers. Unfortunately if you want to create a list-of-lists you will run into referencing errors. Example in Python 2.7.6:

>>> a = [[]]*10
>>> a
[[], [], [], [], [], [], [], [], [], []]
>>> a[0].append(0)
>>> a
[[0], [0], [0], [0], [0], [0], [0], [0], [0], [0]]
>>> 

As you can see, each element is pointing to the same list object. To get around this, you can create a method that will initialize each position to a different object reference.

def init_list_of_objects(size):
    list_of_objects = list()
    for i in range(0,size):
        list_of_objects.append( list() ) #different object reference each time
    return list_of_objects


>>> a = init_list_of_objects(10)
>>> a
[[], [], [], [], [], [], [], [], [], []]
>>> a[0].append(0)
>>> a
[[0], [], [], [], [], [], [], [], [], []]
>>> 

There is likely a default, built-in python way of doing this (instead of writing a function), but I'm not sure what it is. Would be happy to be corrected!

Edit: It's [ [] for _ in range(10)]

Example :

>>> [ [random.random() for _ in range(2) ] for _ in range(5)]
>>> [[0.7528051908943816, 0.4325669600055032], [0.510983236521753, 0.7789949902294716], [0.09475179523690558, 0.30216475640534635], [0.3996890132468158, 0.6374322093017013], [0.3374204010027543, 0.4514925173253973]]
James L.
  • 12,893
  • 4
  • 49
  • 60
  • 22
    I heard that using `append` very often is inferior to list comprehensions. You could create your list of lists via `[ [] for _ in range(10)]`. – M.Herzkamp Aug 04 '16 at 11:34
  • 20
    Upvoted because I was getting mad because I had multi-dimentional array with the same data repeated several times and couldn't figure what was happening before finally finding this answer.^^ I don't understand why it's so low here. – Bregalad Dec 30 '17 at 17:43
  • Numbers are references too. The only thing that saves you is that they're immutable, so the only way to change them is to replace with a different reference. – Mark Ransom Oct 15 '22 at 02:31
  • Thanks, saved me time trying to understand why my 3D list keeps repeating the assignment for all `a[0][0]` when assigned `a[0][0][0]=1` – macroland Feb 02 '23 at 11:25
26

I'm surprised nobody suggest this simple approach to creating a list of empty lists. This is an old thread, but just adding this for completeness. This will create a list of 10 empty lists

x = [[] for i in range(10)]
Bow
  • 987
  • 1
  • 10
  • 19
  • 24
    The most important difference between doing the above vs doing `x = [[]] * 10` is that in the latter, **each element in the list is pointing to the SAME list object**. So unless you simply want 10 copies of the same object, use the `range` based variant as it creates 10 **new** objects. I found this distinction very important. – Mandeep Sandhu Apr 23 '18 at 18:29
23

You can .append(element) to the list, e.g.:

s1.append(i)

What you are currently trying to do is access an element (s1[i]) that does not exist.

My Car
  • 4,198
  • 5
  • 17
  • 50
Mohammed Hossain
  • 1,319
  • 10
  • 19
23

There are two "quick" methods:

x = length_of_your_list
a = [None]*x
# or
a = [None for _ in xrange(x)]

It appears that [None]*x is faster:

>>> from timeit import timeit
>>> timeit("[None]*100",number=10000)
0.023542165756225586
>>> timeit("[None for _ in xrange(100)]",number=10000)
0.07616496086120605

But if you are ok with a range (e.g. [0,1,2,3,...,x-1]), then range(x) might be fastest:

>>> timeit("range(100)",number=10000)
0.012513160705566406
mgoldwasser
  • 14,558
  • 15
  • 79
  • 103
  • 2
    Note that in Python3 you'll have to use `list(range(n))` instead, as `range()` doesn't return a list but is an iterator, and that isn't faster than `[None] * n`. – Skillmon Feb 07 '20 at 21:16
19

The accepted answer has some gotchas. For example:

>>> a = [{}] * 3
>>> a
[{}, {}, {}]
>>> a[0]['hello'] = 5
>>> a
[{'hello': 5}, {'hello': 5}, {'hello': 5}]
>>> 

So each dictionary refers to the same object. Same holds true if you initialize with arrays or objects.

You could do this instead:

>>> b = [{} for i in range(0, 3)]
>>> b
[{}, {}, {}]
>>> b[0]['hello'] = 6
>>> b
[{'hello': 6}, {}, {}]
>>> 
user2233706
  • 6,148
  • 5
  • 44
  • 86
  • Above method works fine for 'single' key-value input for each 'dict' inside list. We can not add another pair to 'b[0]'. So, it is always better to use '.append' or '.extend' method rather than simply assigning the values. And it goes for every combination such as tuple(list), list(list), etc. – Akshay Gaikwad Mar 19 '21 at 18:37
9

How do I create an empty list that can hold 10 elements?

All lists can hold as many elements as you like, subject only to the limit of available memory. The only "size" of a list that matters is the number of elements currently in it.

However, that gives IndexError: list assignment index out of range. Why?

The first time through the loop, i is equal to 0. Thus, we attempt xs[0] = 0. This does not work because there are currently 0 elements in the list, so 0 is not a valid index.

We cannot use indexing to write list elements that don't already exist - we can only overwrite existing ones. Instead, we should use the .append method:

xs = list();
for i in range(0, 9):
   xs.append(i)

The next problem you will note is that your list will actually have only 9 elements, because the end point is skipped by the range function. (As side notes: [] works just as well as list(), the semicolon is unnecessary, and only one parameter is needed for range if you're starting from 0.) Addressing those issues gives:

xs = []
for i in range(10):
    xs.append(i)

However, this is still missing the mark - range is not some magical keyword that's part of the language the way for (or, say, def) is.

In 2.x, range is a function, which directly returns the list that we already wanted:

xs = range(10) # 2.x specific!
# In 3.x, we don't get a list; we can do a lot of things with the
# result, but we can't e.g. append or replace elements.

In 3.x, range is a cleverly designed class, and range(10) creates an instance. To get the desired list, we can simply feed it to the list constructor:

xs = list(range(10)) # correct in 3.x, redundant in 2.x
Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
7

One simple way to create a 2D matrix of size n using nested list comprehensions:

m = [[None for _ in range(n)] for _ in range(n)]
msonsona
  • 1,306
  • 14
  • 20
  • Every nested list is actually a reference to the same list. A quick fix would be the following: `[[None for _ in range(2)].copy() for _ in range(2)]` – Samuel Cabrera Mar 04 '21 at 10:34
6

I'm a bit surprised that the easiest way to create an initialised list is not in any of these answers. Just use a generator in the list function:

list(range(9))
Igor Rodriguez
  • 1,196
  • 11
  • 16
  • 1
    A bit curious as to why anyone comments on this one yet... I'm a python noob and I this one looks like the way to go, but nobody says anything. Maybe the range function could be expensive or something? – AFP_555 Apr 22 '19 at 02:25
  • 3
    This problem is this answer doesn't create an empty list as per question, you will end up with [0, 1, 2, 3, 4, 5, 6, 7 ,8] which is what the range(9) function does. Assuming instantiating a list of Nones is useful rather than filling it with numbers right away – Hansang May 12 '19 at 04:24
  • Why wrap the `range(9)` in `list()`? Doesn't `range(9)` already return a list? – Zyl Aug 27 '19 at 16:21
  • 2
    @Zyl `range` is not a list, nor a generator. It's a built-in immutable subclass of `Sequence`. – Nuno André Nov 14 '19 at 02:53
  • 1
    @AFP_555 I think the real question is why it isn't downvoted more, as it doesn't really answer the question and could have bad unintended consequences. – eric Feb 13 '20 at 19:08
5

Another option is to use numpy for fixed size arrays (of pointers):

> pip install numpy

import numpy as np


a = np.empty(10, dtype=np.object)
a[1] = 2
a[5] = "john"
a[3] = []

If you just want numbers, you can do with numpy:

a = np.arange(10)
Gulzar
  • 23,452
  • 27
  • 113
  • 201
2

Here's my code for 2D list in python which would read no. of rows from the input :

empty = []
row = int(input())

for i in range(row):
    temp = list(map(int, input().split()))
    empty.append(temp)

for i in empty:
    for j in i:
        print(j, end=' ')
    print('')
Praveen Kumar Purushothaman
  • 164,888
  • 24
  • 203
  • 252
Amit Prafulla
  • 381
  • 2
  • 5
2

A list is always "iterable" and you can always add new elements to it:

  1. insert: list.insert(indexPosition, value)
  2. append: list.append(value)
  3. extend: list.extend(value)

In your case, you had instantiated an empty list of length 0. Therefore, when you try to add any value to the list using the list index (i), it is referring to a location that does not exist. Therefore, you were getting the error "IndexError: list assignment index out of range".

You can try this instead:

s1 = list();
for i in range(0,9):
   s1.append(i)

print (s1)

To create a list of size 10(let's say), you can first create an empty array, like np.empty(10) and then convert it to list using arrayName.tolist(). Alternately, you can chain them as well.

            **`np.empty(10).tolist()`**
Tanmoy
  • 789
  • 7
  • 14
0

I came across this SO question while searching for a similar problem. I had to build a 2D array and then replace some elements of each list (in 2D array) with elements from a dict. I then came across this SO question which helped me, maybe this will help other beginners to get around. The key trick was to initialize the 2D array as an numpy array and then using array[i,j] instead of array[i][j].

For reference this is the piece of code where I had to use this :

nd_array = []
for i in range(30):
    nd_array.append(np.zeros(shape = (32,1)))
new_array = []
for i in range(len(lines)):
    new_array.append(nd_array)
new_array = np.asarray(new_array)
for i in range(len(lines)):
    splits = lines[i].split(' ')
    for j in range(len(splits)):
        #print(new_array[i][j])
        new_array[i,j] = final_embeddings[dictionary[str(splits[j])]-1].reshape(32,1)

Now I know we can use list comprehension but for simplicity sake I am using a nested for loop. Hope this helps others who come across this post.

Sanjay Krishna
  • 157
  • 1
  • 7
0

Not technically a list but similar to a list in terms of functionality and it's a fixed length

from collections import deque
my_deque_size_10 = deque(maxlen=10)

If it's full, ie got 10 items then adding another item results in item @index 0 being discarded. FIFO..but you can also append in either direction. Used in say

  • a rolling average of stats
  • piping a list through it aka sliding a window over a list until you get a match against another deque object.

If you need a list then when full just use list(deque object)

DaftVader
  • 105
  • 1
  • 11
-2
s1 = []
for i in range(11):
   s1.append(i)

print s1

To create a list, just use these brackets: "[]"

To add something to a list, use list.append()

chrome
  • 3
  • 2
-2

Make it more reusable as a function.

def createEmptyList(length,fill=None):
    '''
    return a (empty) list of a given length
    Example:
        print createEmptyList(3,-1)
        >> [-1, -1, -1]
        print createEmptyList(4)
        >> [None, None, None, None]
    '''
    return [fill] * length
Kardi Teknomo
  • 1,375
  • 16
  • 24
-5

This code generates an array that contains 10 random numbers.

import random
numrand=[]
for i in range(0,10):
   a = random.randint(1,50)
   numrand.append(a)
   print(a,i)
print(numrand)
  • 4
    Welcome to SO. Your answer doesn't really address the question specifically. Have a look at https://stackoverflow.com/help/how-to-answer – Nick May 28 '18 at 21:02