-5

Similar to other programming languages like C/C++, in Python do we have a way of declaring an array without initializing (something like data[1][3])? Here I have a snippet that creates an empty 2D list:

data=[[]]
data[0]=[1,2,3]
data[1]=[3,4,5] //this will create an error since its out of bound access

In my case, I want to define the number of rows and columns statically. I believe the append() API may help but what can help me better is the traditional way of initializing (since my input data to be copied from elsewhere). I believe, if I can specify the sizes in data[[]], it will solve the problem.

Alec
  • 8,529
  • 8
  • 37
  • 63
Ginu Jacob
  • 1,588
  • 2
  • 19
  • 35
  • I'm not entirely sure, but maybe: `Data = [[[None]*rows]*columns][0]`, with `None` as a placeholder? EDIT: Don't do this, the list just becomes a long list of pointers, so changing `Data[0][0] = 4` will change the first index of all sublists. – Recessive Apr 29 '19 at 03:38
  • @Recessive, take care, with your code you are generating `columns` times references to the same list! – Netwave Apr 29 '19 at 03:41
  • @Netwave Yeh, I thought initialising with `None` would get around that, but obviously not :/ – Recessive Apr 29 '19 at 03:42
  • 1
    You do not have an array; you have a nested `list`. If you want array-like semantics, look into `numpy`. – gmds Apr 29 '19 at 03:43
  • No, Python *doesn't have variable declarations at all*. – juanpa.arrivillaga Apr 29 '19 at 03:46

2 Answers2

1

A couple things:

  1. Python doesn't have variable declarations. Variables are dynamically typed.
  2. Vanilla Python doesn't have arrays. If you want to work with arrays, numpy is much more efficient than nested lists

Now, onto your question, you can scaffold the structure of your "array" using list comprehensions:

y, x = columns, rows

[['_' for _ in range(y)] for _ in range(x)]

or

[[None for _ in range(y)] for _ in range(x)]

As @Tomothy notes, this can be simplified a bit:

[[None] * y for _ in range(x)]
Alec
  • 8,529
  • 8
  • 37
  • 63
  • You can safely do `['_'] * y` and `[None] * y` to simplify it a bit. – iz_ Apr 29 '19 at 04:29
  • Those copy memory addresses and if he tries to change array[y][x] it will change everything in a column – Alec Apr 29 '19 at 04:29
  • No, if you do something like `[[None] * y for _ in range(x)]` it will be fine. – iz_ Apr 29 '19 at 04:30
  • So it only breaks it on the second `*`. Good to know. – Alec Apr 29 '19 at 04:35
  • Or more specifically, it will "break" on mutable objects. – iz_ Apr 29 '19 at 04:54
  • Note, vanilla python does have arrays! They are available in the `array` module, however, their utility is rather limited to holding primitive data types, although they can be very space efficient (an array of unsigned int8 objects can save you oodles of memory compared to a similarly sized list of `int` objects) – juanpa.arrivillaga May 05 '19 at 21:42
0

Use a comprehension to initialize a list:

[[None for _ in range(columns)] for _ in range(rows)]

Example:

>>> data = [[None for _ in range(3)]]
>>> data
[[None, None, None]]
>>> data[1]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range

Notice that in python you need to fill them with some default values, I used None but you can use whatever fits your algorithm.

Netwave
  • 40,134
  • 6
  • 50
  • 93