Felix already provided an excellent answer, but I thought I'd do a speed comparison of the various methods:
- 10.59 sec (105.9 µs/itn) -
copy.deepcopy(old_list) - 10.16 sec (101.6 µs/itn) - pure Python
Copy()method copying classes with deepcopy - 1.488 sec (14.88 µs/itn) - pure Python
Copy()method not copying classes (only dicts/lists/tuples) - 0.325 sec (3.25 µs/itn) -
for item in old_list: new_list.append(item) - 0.217 sec (2.17 µs/itn) -
[i for i in old_list](a list comprehension) - 0.186 sec (1.86 µs/itn) -
copy.copy(old_list) - 0.075 sec (0.75 µs/itn) -
list(old_list) - 0.053 sec (0.53 µs/itn) -
new_list = []; new_list.extend(old_list) - 0.039 sec (0.39 µs/itn) -
old_list[:](list slicing)
So the fastest is list slicing. But be aware that copy.copy(), list[:] and list(list), unlike copy.deepcopy() and the python version don't copy any lists, dictionaries and class instances in the list, so if the originals change, they will change in the copied list too and vice versa.
(Here's the script if anyone's interested or wants to raise any issues:)
from copy import deepcopyclass old_class: def __init__(self): self.blah = 'blah'class new_class(object): def __init__(self): self.blah = 'blah'dignore = {str: None, unicode: None, int: None, type(None): None}def Copy(obj, use_deepcopy=True): t = type(obj) if t in (list, tuple): if t == tuple: # Convert to a list if a tuple to # allow assigning to when copying is_tuple = True obj = list(obj) else: # Otherwise just do a quick slice copy obj = obj[:] is_tuple = False # Copy each item recursively for x in xrange(len(obj)): if type(obj[x]) in dignore: continue obj[x] = Copy(obj[x], use_deepcopy) if is_tuple: # Convert back into a tuple again obj = tuple(obj) elif t == dict: # Use the fast shallow dict copy() method and copy any # values which aren't immutable (like lists, dicts etc) obj = obj.copy() for k in obj: if type(obj[k]) in dignore: continue obj[k] = Copy(obj[k], use_deepcopy) elif t in dignore: # Numeric or string/unicode? # It's immutable, so ignore it! pass elif use_deepcopy: obj = deepcopy(obj) return objif __name__ == '__main__': import copy from time import time num_times = 100000 L = [None, 'blah', 1, 543.4532, ['foo'], ('bar',), {'blah': 'blah'}, old_class(), new_class()] t = time() for i in xrange(num_times): Copy(L) print 'Custom Copy:', time()-t t = time() for i in xrange(num_times): Copy(L, use_deepcopy=False) print 'Custom Copy Only Copying Lists/Tuples/Dicts (no classes):', time()-t t = time() for i in xrange(num_times): copy.copy(L) print 'copy.copy:', time()-t t = time() for i in xrange(num_times): copy.deepcopy(L) print 'copy.deepcopy:', time()-t t = time() for i in xrange(num_times): L[:] print 'list slicing [:]:', time()-t t = time() for i in xrange(num_times): list(L) print 'list(L):', time()-t t = time() for i in xrange(num_times): [i for i in L] print 'list expression(L):', time()-t t = time() for i in xrange(num_times): a = [] a.extend(L) print 'list extend:', time()-t t = time() for i in xrange(num_times): a = [] for y in L: a.append(y) print 'list append:', time()-t t = time() for i in xrange(num_times): a = [] a.extend(i for i in L) print 'generator expression extend:', time()-t