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.