Using deepcopy() or copy() is a good solution. For a simple 2D-array case
y = [row[:] for row in x]
Answer from Ryan Ye on Stack OverflowWhy is copying a list so damn difficult in python?
Copying nested lists in Python - Stack Overflow
How do i copy out one row of a 2d array into a 1d array? - Processing 2.x and 3.x Forum
What is the fastest way to copy a 2D array in Python? - Stack Overflow
Videos
I am sure there is a reason for this design in Python but why is it so difficult to clone a list? Copying a variable is easy
foo = 1 bar = foo bar = 2 print bar # returns 2 print foo # returns 1
But trying to do the same thing, which is what makes sense in my mind coming from other languages, does not work. You have to add the list splice otherwise it doesn't work.
Then I spent a day trying to figure out how to copy a 2d list and that was even more frustrating. I had the following code and none of these worked to properly copy a list without modifying the original.
foo = [[1,2], [3,4], [5,6]]
bar = foo # doesnt work
bar = foo[:] # doesnt work
bar = list(foo) # doesnt work
bar = list(foo[:]) # doesnt work
bar = []
bar += foo # doesnt work
bar = []
bar.append(foo) # doesnt work
for i, x in enumerate(foo):
bar[i] = x[:]
# didnt workI am sure I tried a few more methods and none of them worked. It was finally this method that was the only way I could find to copy a 2d list, modify the new one without affecting the original list
bar = [x[:] for x in foo]
So why is copying a list in python just so hard?
I used a bash variable for setting up the timeit tests:
setup="""
R = 100
C = 100
from copy import deepcopy
import numpy as np
ref = [[i for i in range(C)] for _ in range(R)]
ref_np = np.array(ref)
cp = [[100 for i in range(C)] for _ in range(R)]
cp_np = np.array(cp)
"""
Just for convenience, I also set a temporary alias pybench:
alias pybench='python3.5 -m timeit -s "$setup" $1'
Python 3
Python 3.5.0+ (default, Oct 11 2015, 09:05:38)
Deepcopy:
>>> pybench "cp = deepcopy(ref)" 100 loops, best of 3: 8.29 msec per loopModifying pre-created array using index:
>>> pybench \ "for y in range(R): for x in range(C): cp[y][x] = ref[y][x]" 1000 loops, best of 3: 1.16 msec per loopNested list comprehension:
>>> pybench "cp = [[x for x in row] for row in ref]" 1000 loops, best of 3: 390 usec per loopSlicing:
>>> pybench "cp = [row[:] for row in ref]" 10000 loops, best of 3: 45.8 usec per loopNumPy copy:
>>> pybench "cp_np = np.copy(ref_np)" 100000 loops, best of 3: 6.03 usec per loopCopying to pre-created NumPy array:
>>> pybench "np.copyto(cp_np, ref_np)" 100000 loops, best of 3: 4.52 usec per loop
There is nothing very surprising in these results, as you might have guessed, use NumPy is enormously faster, especially if one avoids creating a new table each time.
To add to the answer from Delgan, numpy copy's documentation says to use numpy.ndarray.copy as the preferred method. So for now, without doing a timing test, I will use numpy.ndarray.copy
https://numpy.org/doc/stable/reference/generated/numpy.copy.html
https://numpy.org/doc/stable/reference/generated/numpy.ndarray.copy.html
I have the following matrix:
matrix = [
[ 9, 0, 0, 0, 8, 0, 3, 0, 0 ],
[ 2, 0, 0, 2, 5, 0, 7, 0, 0 ],
[ 0, 2, 0, 3, 0, 0, 0, 0, 4 ],
] Say that I want to make "new_matrix" have a 3x3 block matrix which is copied from "matrix". In this case, I want new_matrix to have:
new_matrix = [
[8 ,0 ,3 ],
[5, 0, 7 ],
[0, 0, 0 ],
] Essentially, what I want is to tell my program to copy the values from the row index [0:0+2] and from the columns [4:4+2]. I tried using a for-loop to go through the requested indexes and adding those values into new_matrix:
new_matrix = [
[0, 0, 0 ],
[0, 0, 0 ],
[0, 0, 0 ],
]
for i in range(len(matrix[0:0+2])):
for j in range(len(matrix[i][4:4+2])):
new_matrix = matrix[i][j] This doesn't seem to work. What am I doing wrong?