Reputation: 40899
I have a Numpy array and can successfully update all its elements with one line:
array_1 = np.array([1, 2, 3, 4])
array_1 = array_1 / 10.0
print(array_1)
# [0.1 0.2 0.3 0.4] -- Success!
However, when I have a list of Numpy arrays and iterate over them with a for in
loop, I cannot apply the same operation and get back the desired results.
array_1 = np.array([1, 2, 3, 4])
array_2 = np.array([5, 6, 7, 8])
array_3 = np.array([9, 10, 11, 12])
print(array_1) # [1 2 3 4]
print(array_2) # [5 6 7 8]
print(array_3) # [ 9 10 11 12]
for array in [array_1, array_2, array_3]:
array = array / 10.0
print(array_1) # [1 2 3 4] -- No changes??
print(array_2) # [5 6 7 8]
print(array_3) # [ 9 10 11 12]
Why am I unable to update these arrays inside a loop? My understanding is that in the line
for array in [array_1, array_2, array_3]:
array
will be a pointer to each of the three Numpy arrays.
How can I fix this problem?
Upvotes: 1
Views: 2873
Reputation: 1859
You can make a shallow copy of the target array inside the for loop to edit the original.
for array in [array_1,array_2,array_3]:
array[:] = array / 10.0
EDIT With Explanation---
In the for loop the control variable is its own object that deep copies the item being iterated over. We can use the [:] operation to make a shallow copy of the target item that references the original object. The following code demonstrates this concept:
array_1 = ['foo']
print(id(array_1)) # Original object id
for array in [array_1]:
array = [1]
print(id(array)) # Deep copy id
for array in [array_1]:
array[:] = [1]
print(id(array)) # Original object id
Upvotes: 2
Reputation: 1331
Becuse you're only assigning new values to the control variable of the loop, so you need to address the actual elements by indexing:
arrays = [array_1, array_2, array_3]
for i in range(len(arrays)):
arrays[i] = arrays[i] / 10.0
or even more comprehensively:
arrays = [array / 10.0 for array in arrays]
or even by filtering:
arrays = list(filter(lambda x: x / 10.0, arrays))
As @ForceBru
noted in the comments section, in-place division would force the return of a float
type array whereas the original is int
.
So the following was changed in the first code snippet:
arrays[i] /= 10.0 -> arrays[i] = arrays[i] / 10.0
Upvotes: 1