More Python Traps

I recently posted on some Python Traps, focussing on code where changes in the values of sub-routine arguments were not reflected in the calling routines.  The reverse can also be a problem: if an array, a, is passed to a sub-routine in VBA, then a new array, b, with the same values created in the sub-routine using b = a, any changes to b will not be reflected in a.

In Python things work differently; the statement b = a means that the array a is now also called b, so changes to b will also change a, both in the sub-routine and in the calling routine.  This was discussed in some detail in The meaning of = in Python; this post looks at some practical examples, and how to create a new copy of an array, rather than just giving the existing array a new name.

The screenshots below illustrate further variations of the routines discussed in the Python Traps post:

  • An array, x, is read from the spreadsheet and passed to a subroutine, either as a list, a list of lists, or a 1D or 2D Numpy array.
  • In the subroutine an array, y, is created, either with the statement y = x, or with the Python copy or deepcopy commands.
  • y is multiplied by a constant.
  • y is retuned to the calling routine, as the function return value.
  • y and x are returned to the spreadsheet.

In the first three examples below the array x is passed as a Python list or a 1D Numpy array.  When the array y is created with y = x, the changes to y are also seen in x, but when x is created with  y = np.copy(x), x is not affected by the changes to y.  The Python copy function (y = copy.copy(x)) works the same way for a 1D list.

With a 2D list (list of lists) however the y array created with the Python copy function behaves the same as using y = x; the changes in y are also seen in x.  This is because copy only creates a new object for the top level list.  The lower level lists still refer to the same objects as in the x list.  To create a new list of lists at all levels it is necessary to use the Python deepcopy function: y = copy-deepcopy(x).

The numpy copy command however works the same on all levels of Numpy arrays. In the final example below the 2D array x is not affected  by the changes to y, which was created with y = np.copy(x).

This entry was posted in Arrays, Excel, Link to Python, Newton, NumPy and SciPy, PyXLL, UDFs and tagged , , , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.