Suppose you want to create a Python list of the predefined length? And suppose you want to create a list of lists with a certain size? Let’s find out what we can do in Python.
A quick answer
Creating a 1D list of elements
Method 1: Using the multiplication operator (*)
1 2 |
listA = [None]*6 print(listA) |
Output:
[None, None, None, None, None, None]
Method 2: Using a for-loop
1 2 |
listB = [None for _ in range(5)] print(listB) |
Output:
[None, None, None, None, None]
Creating a list of lists (use for-loop)
1 2 |
listC = [[None for _ in range(2)] for _ in range(3)] print(listC) |
Output:
[[None, None], [None, None], [None, None]]
Note: Be careful when creating these lists because things may not happen as you want them to. Please continue reading to find out what can go wrong and how to fix it.
Creating a list of predefined size
Often, programmers create an empty list and then append values to it. In some cases, however, we want a list of specific sizes, and then we can assign values. When creating the list, we will use some default values as placeholders, for example, the None value, an empty string (‘ ‘), etc.
The following are methods that can be used to create a Python list of a given size:
Method 1: Using multiplication operator (*)
1 2 3 4 5 6 7 8 9 10 11 12 |
# Creating lists of size 5 with different placeholders a_list = [None]*5 # None is the default value b_list = ['']*5 # empty string as default c_list = [99]*5 # the default in print("a_list: ", a_list) print("b_list: ", b_list) print("c_list: ", c_list) a_list[2] = 27 #assign 27 to the 2nd element in a_list print("a_list modified: ",a_list) a_list[6] = "nullify" #attempting to assign value outside #the length of the list leads to IndexError print(a_list) |
Output:
a_list [None, None, None, None, None] b_list ['', '', '', '', ''] c_list [99, 99, 99, 99, 99] a_list modified [None, None, 27, None, None] IndexError: list assignment index out of range
In this snippet, we created lists of length 5 (you can use the len() function to check the length of a list) with different placeholders. We also show how to assign (using the ‘=’ operator) value to a list based on an index. Note that any attempt to assign value beyond the size of the list leads to IndexError.
Note: If you want to initialize a 2D list (lists within a list), don’t use the multiplication operator, it will give you results you might not expect (we will discuss this in the next section).
Method 2: Using for-loop
We can also use a for loop to create lists of a pre-decided size. For example,
1 2 3 4 5 |
a_lst = [] # initialize an empty list for _ in range(5): a_lst.append("None") print(a_lst) |
Output:
['None', 'None', 'None', 'None', 'None']
And we can convert this into a list expression as follows:
1 2 |
a_lst = ["None" for _ in range(7)] print(a_lst) |
Output:
['None', 'None', 'None', 'None', 'None', 'None', 'None']
Creating Python list of lists (2D) of predefined sizes
The use of the multiplication operator only works for non-referenced data types like numbers, None, and strings but may not work as you expect for types like lists and sets. For this reason, the use of the multiplication operator is avoided.
What goes wrong?
Let’s see what happens when we use the multiplication operator for initializing a list with referenced elements like lists.
1 2 3 4 5 6 7 8 9 10 11 |
# Creating lists (of size 2 each) within a list (of 3 lists) a = [[None]*2]*3 print(a) # Attempting to assign the first element of the first list value 23 a[0][0] = 23 print(a) # attempt to append "foo" to the first position of list a a[0].append('foo') print(a) |
Output:
[[None, None], [None, None], [None, None]] [[23, None], [23, None], [23, None]] [[23, None, 'foo'], [23, None, 'foo'], [23, None, 'foo']]
On inspection of the printout, the created list in line 2 seems OK, but it is not. To show that, we attempted to assign the value 23 to the first element in the first list. We expected to get [[23, None], [None, None], [None, None]] but we got unusual results. Attempting to append also did not yield the results we wanted. Just like me, you might have expected [“foo”, [None, None], [None, None]]. So what exactly went wrong?
The problem is with references. The object we created creates a list of pointers. Using a multiplication operator with any non-primitive (referenced) object will create a list of pointers to the same object. We can confirm that by using the id(<object>) function in Python, which tells us the identity of <object>.
1 2 |
id_a = [id(i) for i in a] print(id_a) |
Output:
[139675625121024, 139675625121024, 139675625121024]
As you can see, the IDs are the same, meaning each element is pointing to the same list object.
The correct way to do it (use for loop)
The best way to create an initialized list within a list is to use for-loop unless you fully understand the above potential issue and fits what you want to do.
1 2 3 4 5 6 7 8 9 10 11 |
# Creating lists (of size 2 each) within a list (of 3 lists) a = [[None for _ in range(2)] for _ in range(3)] print(a) # assign the first element of the first list value 23 a[0][0] = 23 print(a) # append "foo" to the first position of list a a[0].append('foo') print(a) |
Output:
[[None, None], [None, None], [None, None]] [[23, None], [None, None], [None, None]] [[23, None, 'foo'], [None, None], [None, None]]
This output now fits what you might expect. It is also important to note that appending a value to the first list increased its length to 3.
Conclusion
There are two ways of creating a list of elements of a given size in Python: using a multiplication operator (*) and using a for-loop. However, when creating lists within a list, be careful when using the multiplication operator because it might give you unexpected output; instead, use for-loop.