Home > database >  Assigning loop results into an array using Python
Assigning loop results into an array using Python

Time:04-29

I'm copying some code over into Python from MATLAB and realised certain parts don't transfer as easily. I want to write a loop in Python where the size of the array is increased with every iteration. I.e., assign a new variable to a different index of the array. For sake of example, consider the vector in MATLAB as x = [1 2 3 4 5 6]. The resulting loop would be:

x = [];
for j = 1:6
    x(j,1) = i;
end

Now, in Python I have

r_x = []
for i in range(1, 6):
    x = i
    r_x.append(x)

Surely there is a more efficient way to assign values to an array when iterating in Python? Why is it not possible to do x[i,1] = i (error: list indices must be integers or slices, not tuple) or r_x.append(x) = x (error: 'int' object has no attribute 'append')?

CodePudding user response:

In Python you can't create list elements by assigning to an index. You grow it incrementally using the append() method.

r_x = []
for i in range(1, 7):
    r_x.append(i)
print(r_x)

Python ranges don't include the ending number, so if you want 1 to 6 you have to use range(1, 7).

However, Python also has shortcuts. For example, list comprehensions:

r_x = [i for i in range(1, 7)]

CodePudding user response:

Your two errors are explained by basic Python list and int properties

Make a list:

In [31]: x = [1,2,3]
In [32]: x[1,0] = 4
Traceback (most recent call last):
  Input In [32] in <cell line: 1>
    x[1,0] = 4
TypeError: list indices must be integers or slices, not tuple

When 1,0 is a tuple (same as (1,0)). Lists do not allow such an index. numpy arrays, do, but that's another story.

Lists can be indexed with a scalar, an integer, that's in the right range. Too large a index, and you'll get a list index out of range. Lists don't grow to accommodate the index.

In [33]: x[1]
Out[33]: 2
In [34]: x[1] = 4
In [35]: x
Out[35]: [1, 4, 3]

List append is relatively efficient. The underlying data structure has "head room" that permits such growth.

In [36]: x.append(4)
In [37]: x
Out[37]: [1, 4, 3, 4]

Your second error must have been the result of assigning an int to the variable:

In [40]: y = 3
In [41]: y.append(3)
Traceback (most recent call last):
  Input In [41] in <cell line: 1>
    y.append(3)
AttributeError: 'int' object has no attribute 'append'

Only a list class object has an append method.

The basic data structure in MATLAB is a 2d matrix. It has a known size. It's been years since I worked extensively in MATLAB, but at the time, we tried to avoid iterations, preferring to work with 'whole-matrix' approaches. I don't recall being able to grow a matrix by simply indexing new values. Even if we could, it wouldn't have been efficient. In newer MATLAB, there's a lot of jit compiling, that lets you get away with a lot of things that would been inefficient earlier. Still, I suspect there's a time penalty to such practices.

I wonder, for example, if this is faster:

x = zeros(6,1);
for j = 1:6
    x(j,1) = i;
end

Or better yet

x = [1:6].'

numpy arrays are closer to MATLAB matrices in character. But there are enough differences to catch wayward MATLAB users off guard.

  • Related