Friday, September 12, 2008

Python and list copies

While working on a tool at Reel FX, I couldn't figure out why the data lists across several different class instances were all returning the same information. Normally working with lists in Python is tons-o'-fun (especially when compared to the gymnastics required to do similar operations in MEL), but that fun can come to a screeching halt if you forget one little important detail: copying a list doesn't necessarily copy the list.

For example, say there's a list assigned as follows:
   data = ["apples","oranges","pears"]
Some time later you want stuff to be a copy of data:
   stuff = data
If you've come to Python with some previous programming/scripting experience, you might assume (as I've done more than once) that this would do the trick. However, that just tells stuff to reference the list assigned to data. If you end up changing data later on, and then look at stuff, you'll notice that it shows the same changes. That's because they're both pointing to the same list in memory.

So how does one get around this little annoyance? Pretty simply, actually:
   stuff = data[:]
That bit on the end tells Python to make stuff equal to the entire contents of data, instead of making it just another pointer. To be more accurate, it duplicates the list to which data is pointing, and then points stuff to that new list.

Dictionaries also exhibit this same point-instead-of-copy behavior, but the syntax is different if you want to make a true copy:
   newdict = olddict.copy()
(Pardon the crazy formatting. I've never tried to insert code blocks into a blog post, and getting it to look decent with the controls available in the Blogger editor is driving me nuts. Methinks it's time to consider an alternative blogging system...)

1 comment:

kattkieru said...

Great tip. Funny, too, that I ran into a similar issue this week. ^_^