How to initialize a two-dimensional array in Python?

Question:

I’m beginning python and I’m trying to use a two-dimensional list, that I initially fill up with the same variable in every place. I came up with this:

def initialize_twodlist(foo):
    twod_list = []
    new = []
    for i in range (0, 10):
        for j in range (0, 10):
            new.append(foo)
        twod_list.append(new)
        new = []

It gives the desired result, but feels like a workaround. Is there an easier/shorter/more elegant way to do this?

Asked By: thepandaatemyface

||

Answers:

[[foo for x in xrange(10)] for y in xrange(10)]

Usually when you want multidimensional arrays you don’t want a list of lists, but rather a numpy array or possibly a dict.

For example, with numpy you would do something like

import numpy
a = numpy.empty((10, 10))
a.fill(foo)
Answered By: Mike Graham

You can use a list comprehension:

x = [[foo for i in range(10)] for j in range(10)]
# x is now a 10x10 array of 'foo' (which can depend on i and j if you want)
Answered By: Adam Rosenfield

A pattern that often came up in Python was

bar = []
for item in some_iterable:
    bar.append(SOME EXPRESSION)

which helped motivate the introduction of list comprehensions, which convert that snippet to

bar = [SOME_EXPRESSION for item in some_iterable]

which is shorter and sometimes clearer. Usually, you get in the habit of recognizing these and often replacing loops with comprehensions.

Your code follows this pattern twice

twod_list = []                                                             
for i in range (0, 10):                               
    new = []                   can be replaced        } this too
    for j in range (0, 10):    } with a list          /
        new.append(foo)       / comprehension        /
    twod_list.append(new)                           /
Answered By: Mike Graham

This way is faster than the nested list comprehensions

[x[:] for x in [[foo] * 10] * 10]    # for immutable foo!

Here are some python3 timings, for small and large lists

$python3 -m timeit '[x[:] for x in [[1] * 10] * 10]'
1000000 loops, best of 3: 1.55 usec per loop

$ python3 -m timeit '[[1 for i in range(10)] for j in range(10)]'
100000 loops, best of 3: 6.44 usec per loop

$ python3 -m timeit '[x[:] for x in [[1] * 1000] * 1000]'
100 loops, best of 3: 5.5 msec per loop

$ python3 -m timeit '[[1 for i in range(1000)] for j in range(1000)]'
10 loops, best of 3: 27 msec per loop

Explanation:

[[foo]*10]*10 creates a list of the same object repeated 10 times. You can’t just use this, because modifying one element will modify that same element in each row!

x[:] is equivalent to list(X) but is a bit more efficient since it avoids the name lookup. Either way, it creates a shallow copy of each row, so now all the elements are independent.

All the elements are the same foo object though, so if foo is mutable, you can’t use this scheme., you’d have to use

import copy
[[copy.deepcopy(foo) for x in range(10)] for y in range(10)]

or assuming a class (or function) Foo that returns foos

[[Foo() for x in range(10)] for y in range(10)]
Answered By: John La Rooy

If it’s a sparsely-populated array, you might be better off using a dictionary keyed with a tuple:

dict = {}
key = (a,b)
dict[key] = value
...
Answered By: btk

As @Arnab and @Mike pointed out, an array is not a list. Few differences are 1) arrays are fixed size during initialization 2) arrays normally support lesser operations than a list.

Maybe an overkill in most cases, but here is a basic 2d array implementation that leverages hardware array implementation using python ctypes(c libraries)

import ctypes
class Array:
    def __init__(self,size,foo): #foo is the initial value
        self._size = size
        ArrayType = ctypes.py_object * size
        self._array = ArrayType()
        for i in range(size):
            self._array[i] = foo
    def __getitem__(self,index):
        return self._array[index]
    def __setitem__(self,index,value):
        self._array[index] = value
    def __len__(self):
        return self._size

class TwoDArray:
    def __init__(self,columns,rows,foo):
        self._2dArray = Array(rows,foo)
        for i in range(rows):
            self._2dArray[i] = Array(columns,foo)

    def numRows(self):
        return len(self._2dArray)
    def numCols(self):
        return len((self._2dArray)[0])
    def __getitem__(self,indexTuple):
        row = indexTuple[0]
        col = indexTuple[1]
        assert row >= 0 and row < self.numRows() 
               and col >=0 and col < self.numCols(),
               "Array script out of range"
        return ((self._2dArray)[row])[col]

if(__name__ == "__main__"):
    twodArray = TwoDArray(4,5,5)#sample input
    print(twodArray[2,3])
Answered By: Antony Thomas

This is the best I’ve found for teaching new programmers, and without using additional libraries. I’d like something better though.

def initialize_twodlist(value):
    list=[]
    for row in range(10):
        list.append([value]*10)
    return list
Answered By: Paul Vincent Craven

To initialize a two-dimensional array in Python:

a = [[0 for x in range(columns)] for y in range(rows)]
Answered By: Vipul

use the simplest think to create this.

wtod_list = []

and add the size:

wtod_list = [[0 for x in xrange(10)] for x in xrange(10)]

or if we want to declare the size firstly. we only use:

   wtod_list = [[0 for x in xrange(10)] for x in xrange(10)]
Answered By: indi60

You can do just this:

[[element] * numcols] * numrows

For example:

>>> [['a'] *3] * 2
[['a', 'a', 'a'], ['a', 'a', 'a']]

But this has a undesired side effect:

>>> b = [['a']*3]*3
>>> b
[['a', 'a', 'a'], ['a', 'a', 'a'], ['a', 'a', 'a']]
>>> b[1][1]
'a'
>>> b[1][1] = 'b'
>>> b
[['a', 'b', 'a'], ['a', 'b', 'a'], ['a', 'b', 'a']]
Answered By: hithwen

Here is an easier way :

import numpy as np
twoD = np.array([[]*m]*n)

For initializing all cells with any ‘x’ value use :

twoD = np.array([[x]*m]*n
Answered By: user3650331
Matrix={}
for i in range(0,3):
  for j in range(0,3):
    Matrix[i,j] = raw_input("Enter the matrix:")
Answered By: Sparsh

To initialize a two-dimensional list in Python, use

t = [ [0]*3 for i in range(3)]

But don’t use [[v]*n]*n, it is a trap!

>>> a = [[0]*3]*3
>>> a
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
>>> a[0][0]=1
>>> a
[[1, 0, 0], [1, 0, 0], [1, 0, 0]]
Answered By: Jason CHAN
from random import randint
l = []

for i in range(10):
    k=[]
    for j in range(10):
        a= randint(1,100)
        k.append(a)

    l.append(k)




print(l)
print(max(l[2]))

b = []
for i in range(10):
    a = l[i][5]
    b.append(a)

print(min(b))
Answered By: KANDARP JAYESH SHAH

Incorrect Approach: [[None*m]*n]

>>> m, n = map(int, raw_input().split())
5 5
>>> x[0][0] = 34
>>> x
[[34, None, None, None, None], [34, None, None, None, None], [34, None, None, None, None], [34, None, None, None, None], [34, None, None, None, None]]
>>> id(x[0][0])
140416461589776
>>> id(x[3][0])
140416461589776

With this approach, python does not allow creating different address space for the outer columns and will lead to various misbehaviour than your expectation.

Correct Approach but with exception:

y = [[0 for i in range(m)] for j in range(n)]
>>> id(y[0][0]) == id(y[1][0])
False

It is good approach but there is exception if you set default value to None

>>> r = [[None for i in range(5)] for j in range(5)]
>>> r
[[None, None, None, None, None], [None, None, None, None, None], [None, None, None, None, None], [None, None, None, None, None], [None, None, None, None, None]]
>>> id(r[0][0]) == id(r[2][0])
True

So set your default value properly using this approach.

Absolute correct:

Follow the mike’s reply of double loop.

Answered By: patilnitin
t = [ [0]*10 for i in [0]*10]

for each element a new [0]*10 will be created ..

Answered By: user9269722

Often I use this approach for initializing a 2-dimensional array

n=[[int(x) for x in input().split()] for i in range(int(input())]

Answered By: user6025787
twod_list = [[foo for _ in range(m)] for _ in range(n)]

for n is number of rows, and m is the number of column, and foo is the value.

Answered By: Moustafa Saleh

The general pattern to add dimensions could be drawn from this series:

x = 0
mat1 = []
for i in range(3):
    mat1.append(x)
    x+=1
print(mat1)


x=0
mat2 = []
for i in range(3):
    tmp = []
    for j in range(4):
        tmp.append(x)
        x+=1
    mat2.append(tmp)

print(mat2)


x=0
mat3 = []
for i in range(3):
    tmp = []
    for j in range(4):
        tmp2 = []
        for k in range(5):
            tmp2.append(x)
            x+=1
        tmp.append(tmp2)
    mat3.append(tmp)

print(mat3)
Answered By: juanfal

The important thing I understood is: While initializing an array(in any dimension) We should give a default value to all the positions of array. Then only initialization completes. After that, we can change or receive new values to any position of the array. The below code worked for me perfectly

N=7
F=2

#INITIALIZATION of 7 x 2 array with deafult value as 0
ar=[[0]*F for x in range(N)]

#RECEIVING NEW VALUES TO THE INITIALIZED ARRAY
for i in range(N):
    for j in range(F):
        ar[i][j]=int(input())
print(ar)

Answered By: Fairoos Ok

If you use numpy, you can easily create 2d arrays:

import numpy as np

row = 3
col = 5
num = 10
x = np.full((row, col), num)

x

array([[10, 10, 10, 10, 10],
       [10, 10, 10, 10, 10],
       [10, 10, 10, 10, 10]])

To initialize a 2-dimensional array use:
arr = [[]*m for i in range(n)]

actually,
arr = [[]*m]*n will create a 2D array in which all n arrays will point to same array, so any change in value in any element will be reflected in all n lists

for more further explanation visit : https://www.geeksforgeeks.org/python-using-2d-arrays-lists-the-right-way/

Answered By: Abhimanyu
row=5
col=5
[[x]*col for x in [b for b in range(row)]]

The above will give you a 5×5 2D array

[[0, 0, 0, 0, 0],
 [1, 1, 1, 1, 1],
 [2, 2, 2, 2, 2],
 [3, 3, 3, 3, 3],
 [4, 4, 4, 4, 4]]

It is using nested list comprehension.
Breakdown as below:

[[x]*col for x in [b for b in range(row)]]

[x]*col –> final expression that is evaluated
for x in –> x will be the value provided by the iterator
[b for b in range(row)]] –> Iterator.

[b for b in range(row)]] this will evaluate to [0,1,2,3,4] since row=5
so now it simplifies to

[[x]*col for x in [0,1,2,3,4]]

This will evaluate to
[[0]*5 for x in [0,1,2,3,4]] –> with x=0 1st iteration
[[1]*5 for x in [0,1,2,3,4]] –> with x=1 2nd iteration
[[2]*5 for x in [0,1,2,3,4]] –> with x=2 3rd iteration
[[3]*5 for x in [0,1,2,3,4]] –> with x=3 4th iteration
[[4]*5 for x in [0,1,2,3,4]] –> with x=4 5th iteration

Answered By: Satya
lst=[[0]*n]*m
np.array(lst)

initialize all matrix m=rows and n=columns

Another way is to use a dictionary to hold a two-dimensional array.

twoD = {}
twoD[0,0] = 0
print(twoD[0,0]) # ===> prints 0

This just can hold any 1D, 2D values and to initialize this to 0 or any other int value, use collections.

import collections
twoD = collections.defaultdict(int)
print(twoD[0,0]) # ==> prints 0
twoD[1,1] = 1
print(twoD[1,1]) # ==> prints 1
Answered By: Tej91

Code:

num_rows, num_cols = 4, 2
initial_val = 0
matrix = [[initial_val] * num_cols for _ in range(num_rows)]
print(matrix) 
# [[0, 0], [0, 0], [0, 0], [0, 0]]

initial_val must be immutable.

Answered By: Abhishek Bhatia

Initializing a 2D matrix of size m X n with 0

m,n = map(int,input().split())
l = [[0 for i in range(m)] for j in range(n)]
print(l)
Answered By: valkyrie55

For those who are confused why [['']*m]*n is not good to use.

Python uses a system known as “Call by Object Reference” or “Call by assignment”.(More info)

Best way is [['' for i in range(columns)] for j in range(rows)]
This will solve all the problems.

For more Clarification
Example:

>>> x = [['']*3]*3
[['', '', ''], ['', '', ''], ['', '', '']]
>>> x[0][0] = 1
>>> print(x)
[[1, '', ''], [1, '', ''], [1, '', '']]
>>> y = [['' for i in range(3)] for j in range(3)]
[['', '', ''], ['', '', ''], ['', '', '']]
>>> y[0][0]=1
>>> print(y)
[[1, '', ''], ['', '', ''], ['', '', '']]
Answered By: Tushar

I use it this way to create MxN matrix where m = number(rows) and n = number(columns).

arr = [[None]*(n) for _ in range(m)]
Answered By: Nishan B

An empty 2D matrix may be initialized in the following manner:

temp=[[],[]]

Answered By: Rashid Kamal
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.