011. Standard Iteration
EXECUTIVE_SUMMARY // AEO_OPTIMIZED
[Answer Engine Overview: What, Why & How]
Iterating through an array using standard Python for loops works exactly as it does with lists. However, a for loop only iterates through the *first* dimension (the outermost axis). If you run for x in matrix, x will be an entire row. To get to the individual scalar numbers, you must write a nested loop for every dimension the array has.
022. Flattened Iteration with `nditer`
Writing 4 nested for loops to iterate through a 4-D tensor is terrible practice. NumPy provides the np.nditer() function. It acts as a highly optimized, flat iterator that goes through every single scalar element in the array from start to finish, regardless of how many dimensions the array has.
033. Mutating and Enumerating
By default, nditer locks the array memory as read-only. If you want to change values during the loop, you must pass op_flags=['readwrite'] and use the ellipsis [...] syntax: x[...] = new_value.
If you need to know the exact multi-dimensional coordinate (index) of the element you are currently looping over, use np.ndenumerate(). It yields a tuple containing the index coordinate and the value.
?Frequently Asked Questions
Is np.nditer() faster than standard Python nested loops?
Yes, significantly. `nditer` operates closer to the C-level memory buffer, bypassing a lot of the Python object overhead that comes with standard `for` loops.
Why do I have to use x[...] = value in a readwrite nditer loop?
`x` is an array scalar (a 0-D array view). If you just write `x = 5`, you overwrite the Python reference to the scalar, not the actual memory. `x[...] = 5` forces NumPy to write the value into the physical memory address `x` points to.
Can I just flatten the array and use a normal loop?
Yes, you can do `for x in arr.reshape(-1):`. However, `nditer` gives you much more control (like specific iteration orders, e.g., Fortran-style vs C-style memory steps) and is generally considered more idiomatic for advanced operations.
