Python普通列表与numpy数组的行为差异:二维元素交换问题解析
Great question—this is a super common gotcha when moving from Python lists to numpy, and it all boils down to how each structure stores and references data. Let’s start with concrete examples to see the difference, then dive into the "why".
Example 1: Swapping with Python 2D Lists
Let’s say we have a 2D list, and we want to swap its first and second rows using a temp variable:
# Python list py_list = [[1, 2], [3, 4]] temp = py_list[0] py_list[0] = py_list[1] py_list[1] = temp print(py_list) # Output: [[3, 4], [1, 2]] ✅ Swapped successfully!
This works because each element in a Python list is a separate reference to an independent object. When we assign temp = py_list[0], we’re storing a reference to the first sublist [1,2]. Even after we overwrite py_list[0] with py_list[1], temp still points to the original [1,2]—so when we assign py_list[1] = temp, we’re putting that original sublist back into the second position.
Example 2: The Numpy "Failure" Case
Now let’s try the exact same temp-variable swap with a numpy array:
import numpy as np np_arr = np.array([[1, 2], [3, 4]]) temp = np_arr[0] np_arr[0] = np_arr[1] np_arr[1] = temp print(np_arr) # Output: [[3, 4], [3, 4]] ❌ No swap—both rows are the same!
Wait, what happened? This is the behavior you’re noticing. The issue here is how numpy handles indexing:
- Numpy returns views, not copies, when you index into an array (unless you explicitly use
.copy()). When we dotemp = np_arr[0],tempisn’t a separate object—it’s a view that points directly to the same memory block as the first row ofnp_arr. - So when we run
np_arr[0] = np_arr[1], we overwrite the first row’s memory with[3,4]. Sincetempis a view of that same memory, it now also holds[3,4]. - Finally,
np_arr[1] = tempjust copies[3,4]into the second row—so both rows end up the same.
How to Fix the Numpy Swap
If you want to replicate the list behavior in numpy, you need to create a copy of the row instead of a view. Here’s how:
np_arr = np.array([[1, 2], [3, 4]]) temp = np_arr[0].copy() # Make a copy instead of a view np_arr[0] = np_arr[1] np_arr[1] = temp print(np_arr) # Output: [[3, 4], [1, 2]] ✅ Now it works!
Alternatively, you can use tuple unpacking directly (which numpy handles correctly because it evaluates the right-hand side first before assigning):
np_arr[0], np_arr[1] = np_arr[1], np_arr[0] print(np_arr) # Output: [[3,4], [1,2]] ✅ Also works!
Core Takeaway
- Python Lists: Each element is a reference to a separate object. Swapping elements swaps these references, so original objects stay intact unless you modify them directly.
- Numpy Arrays: Indexing returns views into the same contiguous memory block. If you use a temp variable that’s a view, modifying the original array will alter the temp variable too. Always use
.copy()if you need to preserve the original value of a slice/row.
内容的提问来源于stack exchange,提问作者Lockon2000

