290

I would like to know how i can initialize an array(or list), yet to be populated with values, to have a defined size.

For example in C:

int x[5]; /* declared without adding elements*/

How do I do that in Python?

bad_coder
  • 11,289
  • 20
  • 44
  • 72
kbb
  • 3,193
  • 3
  • 18
  • 15
  • 3
    All of these: http://stackoverflow.com/search?q=%5Bpython%5D+array+of+fixed+size. – S.Lott May 26 '11 at 17:38
  • 1
    possible duplicate of [Python, forcing a list to a fixed size](http://stackoverflow.com/questions/5944708/python-forcing-a-list-to-a-fixed-size) Or maybe this: http://stackoverflow.com/questions/4056768/how-to-declare-array-of-zeros-in-python-or-an-array-of-a-certain-size – S.Lott May 26 '11 at 17:38
  • 3
    The more interesting question is *why* you want to do this. Most of the situations where I've seen this needed are because of bad decisions. – Noufal Ibrahim May 26 '11 at 17:40
  • 3
    You almost never need this. In 99% of the cases you can generate the values in one swoop, e.g. using a list comprehension, or you simply start with `[]` and `.append()` or `.expand()` in a `while` loop or something like that (lists are over-allocating so resizing is amortized O(1)). –  May 26 '11 at 17:41
  • 3
    You should explain your motivation for needing this. Performance? Security? Interfacing with C/C++/NumPy/...? – smci Feb 09 '12 at 23:25
  • `x = [0]*5` will provide the equal opposite of `int x[5]` – Naresh Joshi Dec 01 '17 at 12:10
  • A C array *has* its elements as soon as it’s created, even if you can’t use them yet because their values are indeterminate. – Davis Herring Sep 08 '18 at 21:53
  • Also you can `[None for i in range(26)]` – GeRyCh Apr 20 '20 at 14:16
  • I'm not sure why this was closed, the question linked and used to close this specified a list. A better answer to declare an integer array of size 'length' is: import array my_array = array.array( 'h', [ 0 ] * length ) – yamex5 Apr 25 '20 at 05:23
  • Initializing an array in advance of filling it can be useful for dynamic programming algorithms, where the order in which the array is filled is not straightforward. For example, I can't imagine an easy way to fill a 2D array diagonally using list comprehensions – The Bic Pen Nov 01 '21 at 14:54

11 Answers11

406

You can use:

>>> lst = [None] * 5
>>> lst
[None, None, None, None, None]
samplebias
  • 37,113
  • 6
  • 107
  • 103
  • 15
    The question specified ".. yet to be populated with values". The Python docs indicate "`None` is typically used to represent absence of a value". My example produced such a list of the defined size, in the shortest amount of code. Its the closest thing in idiomatic Python at the time the question was asked. – samplebias Aug 25 '14 at 21:08
  • 4
    This meets the requirements of the question because you have a defined size array and you can index one of the five elements without getting an `IndexError`. This is the closest thing to the C expression. – user2233706 Oct 26 '14 at 17:43
  • 2
    @user2233706 It would be closer to C if the array were populated with zeros. – yamex5 Apr 25 '20 at 04:47
  • 6
    You can do lst = [0] * 5 is you want ```>>> [0]*5``` ```[0, 0, 0, 0, 0]``` – kamayd Jun 10 '20 at 17:33
  • 11
    One thing to note: all elements in the list will have initially the same id (or memory address). When you change any element later on in the code, this will impact only the specified value, - HOWEVER - if you create a list of custom objects in this way (using the int multiplier) and later on you change any property of the custom object, this will change ALL the objects in the list. – asa Jan 22 '21 at 21:59
  • this is not fixed size still one can use append method to add in a list – Azhar Uddin Sheikh Oct 25 '21 at 18:16
  • it is both mutable, extendable and not of fixed type. It is not actually an array at all. There is actually a module `array` which has a fixed length, mutable singularly typed members accessibly by index. This is the most relevant way of using a C-like arrray. Numpy Arrays have some common features, but limitations/quirks which make them not a suitable parallel of C arrays – sconfluentus May 25 '22 at 01:26
113

Why don't these questions get answered with the obvious answer?

a = numpy.empty(n, dtype=object)

This creates an array of length n that can store objects. It can't be resized or appended to. In particular, it doesn't waste space by padding its length. This is the Python equivalent of Java's

Object[] a = new Object[n];

If you're really interested in performance and space and know that your array will only store certain numeric types then you can change the dtype argument to some other value like int. Then numpy will pack these elements directly into the array rather than making the array reference int objects.

Alec
  • 1,986
  • 4
  • 23
  • 47
Pat Morin
  • 1,688
  • 1
  • 12
  • 12
  • 122
    If it had been that obvious, though, someone else would have provided this.. again, importing a library just to get this functionality may not be the best option. – icedwater Mar 12 '14 at 01:44
  • 29
    Except that this is the only answer here which is actually correct. The OP didn't specify that module loading was prohibited. Nor did he ask for a list. The question is very specific and this answer is correct. +1 – Dave Jul 02 '14 at 11:17
  • 37
    adding a large module such as numpy is an unnecessary overhead – shaw2thefloor Mar 28 '17 at 10:58
  • 1
    Can you explain why the choice of ``dtype=object`` as opposed to some other ``dtype``? – PatrickT Nov 07 '18 at 19:45
  • 1
    Just to clarify, does this implementation have the typical O(1) access time of an array as opposed to the O(n) access time of a linked list? – user8773963 Jan 12 '20 at 20:34
  • 1
    They said Python, not Python + Numpy. Numpy is not a trivial add-on, either. It can't be uninstalled and therefore is highly problematic for embedded Python uses. – Jiminion Jun 10 '23 at 21:57
61

Do this:

>>> d = [ [ None for y in range( 2 ) ] for x in range( 2 ) ]
>>> d
[[None, None], [None, None]]
>>> d[0][0] = 1
>>> d
[[1, None], [None, None]]

The other solutions will lead to this kind of problem:

>>> d = [ [ None ] * 2 ] * 2
>>> d
[[None, None], [None, None]]
>>> d[0][0] = 1
>>> d
[[1, None], [1, None]]
TTimo
  • 1,276
  • 1
  • 13
  • 20
  • 1
    Good answer. The problem you mention screwed me up at a programming competition. Do you know the exact mechanics under the bonnet to cause this? – A.L. Verminburger Jan 12 '20 at 09:11
  • Python copies "plain old data types" by value, and the rest by reference, and it's not always clear when one or the other is happening. – TTimo Jan 13 '20 at 14:31
  • 1
    in case anyone wondering, the behavior is (TLDR first multiplier creates `n` length array, second multiplier creates a list of the arrays of `m` length by copying the first array by reference) explained here https://docs.python.org/2/faq/programming.html#how-do-i-create-a-multidimensional-list – Jimson James Apr 02 '21 at 20:02
  • I had the exact problem. – Jinhua Wang Mar 21 '22 at 13:03
18

The best bet is to use the numpy library.

from numpy import ndarray

a = ndarray((5,),int)
Glorfindel
  • 21,988
  • 13
  • 81
  • 109
lafras
  • 8,712
  • 4
  • 29
  • 28
16
>>> import numpy
>>> x = numpy.zeros((3,4))
>>> x
array([[ 0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.]])
>>> y = numpy.zeros(5)   
>>> y
array([ 0.,  0.,  0.,  0.,  0.])

x is a 2-d array, and y is a 1-d array. They are both initialized with zeros.

kaamen
  • 185
  • 1
  • 4
13

An easy solution is x = [None]*length, but note that it initializes all list elements to None. If the size is really fixed, you can do x=[None,None,None,None,None] as well. But strictly speaking, you won't get undefined elements either way because this plague doesn't exist in Python.

Alexander Gessler
  • 45,603
  • 7
  • 82
  • 122
  • 5
    For most C use cass of an array, a normal (non-fixed) list is the idiomatic python equivalent. This is an answer to the question, as it probably helps the the OP (who is transitting from C to Python) most. – Alexander Gessler Sep 26 '13 at 17:33
12
>>> n = 5                     #length of list
>>> list = [None] * n         #populate list, length n with n entries "None"
>>> print(list)
[None, None, None, None, None]

>>> list.append(1)            #append 1 to right side of list
>>> list = list[-n:]          #redefine list as the last n elements of list
>>> print(list)
[None, None, None, None, 1]

>>> list.append(1)            #append 1 to right side of list
>>> list = list[-n:]          #redefine list as the last n elements of list
>>> print(list)
[None, None, None, 1, 1]

>>> list.append(1)            #append 1 to right side of list
>>> list = list[-n:]          #redefine list as the last n elements of list
>>> print(list)
[None, None, 1, 1, 1]

or with really nothing in the list to begin with:

>>> n = 5                     #length of list
>>> list = []                 # create list
>>> print(list)
[]

>>> list.append(1)            #append 1 to right side of list
>>> list = list[-n:]          #redefine list as the last n elements of list
>>> print(list)
[1]

on the 4th iteration of append:

>>> list.append(1)            #append 1 to right side of list
>>> list = list[-n:]          #redefine list as the last n elements of list
>>> print(list)
[1,1,1,1]

5 and all subsequent:

>>> list.append(1)            #append 1 to right side of list
>>> list = list[-n:]          #redefine list as the last n elements of list
>>> print(list)
[1,1,1,1,1]
litepresence
  • 3,109
  • 1
  • 27
  • 35
3

Well I would like to help you by posting a sample program and its output

Program:

t = input("")
x = [None]*t
y = [[None]*t]*t

for i in range(1, t+1):
    x[i-1] = i;

    for j in range(1, t+1):
        y[i-1][j-1] = j;

print x
print y

Output :-

2
[1, 2]
[[1, 2], [1, 2]]

I hope this clears some very basic concept of yours regarding their declaration. To initialize them with some other specific values, like initializing them with 0.. you can declare them as:

x = [0]*10

Hope it helps..!! ;)

JimiDini
  • 2,039
  • 12
  • 19
Archit
  • 79
  • 1
  • 1
    Your code doesn't define fixes-size array/list as requested in question. You just put some values in list, which still can be of any length – JimiDini Sep 26 '13 at 15:48
  • 2
    and why is it -1 while the +12 answer states the same way of doing so? – lejlot Sep 26 '13 at 15:52
  • @lejlot because +12 answer is wrong too and similarly doesn't answer original question – JimiDini Sep 26 '13 at 15:58
  • 2
    I would not call them wrong, python simply does not have such low level access to memory management, while provided answers are really close to the expected behavior from the practical point of view – lejlot Sep 26 '13 at 16:07
  • 6
    This solution does **not** do what you expect it to. `[[None] * t] * t` will create a list of `t` copies of **the same** "row". See [this question](https://docs.python.org/2/faq/programming.html#how-do-i-create-a-multidimensional-list) in the Python FAQ. – Lynn Dec 17 '14 at 14:43
  • @Lynn Thanks for this. I was puzzled for about a whole hour before I came here. – WISERDIVISOR Dec 07 '20 at 14:18
2

You can try using Descriptor, to limit the size

class fixedSizeArray(object):
    def __init__(self, arraySize=5):
        self.arraySize = arraySize
        self.array = [None] * self.arraySize

    def __repr__(self):
        return str(self.array)

    def __get__(self, instance, owner):
        return self.array

    def append(self, index=None, value=None):
        print "Append Operation cannot be performed on fixed size array"
        return

    def insert(self, index=None, value=None):
        if not index and index - 1 not in xrange(self.arraySize):
            print 'invalid Index or Array Size Exceeded'
            return
        try:
            self.array[index] = value
        except:
            print 'This is Fixed Size Array: Please Use the available Indices'


arr = fixedSizeArray(5)
print arr
arr.append(100)
print arr
arr.insert(1, 200)
print arr
arr.insert(5, 300)
print arr

OUTPUT:

[None, None, None, None, None]
Append Operation cannot be performed on fixed size array
[None, None, None, None, None]
[None, 200, None, None, None]
This is Fixed Size Array: Please Use the available Indices
[None, 200, None, None, None]
Siva Cn
  • 929
  • 4
  • 10
  • 1
    What point does your `def __get__(self, instance, owner):` have in this context? Instead, you should define `__(set|get|del)item__()`, the latter setting it/them to `None`. – glglgl Mar 24 '14 at 14:07
2

One thing I find easy to do is i set an array of empty strings for the size I prefer, for example

Code:

import numpy as np

x= np.zeros(5,str)
print x

Output:

['' '' '' '' '']

Hope this is helpful :)

lucian.pantelimon
  • 3,673
  • 4
  • 29
  • 46
0

If you are working with bytes you could use the builtin bytearray. If you are working with other integral types look at the builtin array.

Specifically understand that a list is not an array.

If, for example, you are trying to create a buffer for reading file contents into you could use bytearray as follows (there are better ways to do this but the example is valid):

with open(FILENAME, 'rb') as f:
    data = bytearray(os.path.getsize(FILENAME))
    f.readinto(data)

In this snippet the bytearray memory is preallocated with the fixed length of FILENAMEs size in bytes. This preallocation allows the use of the buffer protocol to more efficiently read the file into a mutable buffer without an array copy. There are yet better ways to do this but I believe this provides one answer to your question.

Dave
  • 764
  • 7
  • 17