I'm a Idiot: How to Copy a Nested List in Python?

Perm URL with updates: http://xahlee.org/perl-python/copy_a_list.html

Copying a Flat List

Copy by Reference

If you do this list_a = list_b, that'll copy a reference. That means: modifying one list also modifies the other. Example:

# python
list_a = [3, 4, 5]
list_b = list_a
list_a[0] = 7
print list_b # returns [7, 4, 5]

You can check by using the “id” function. The “id” returns the object's memory address.

# python
aa = [3, 4, 5]
print id(aa) # sample output: 2129927212
# python
list_a = [3, 4, 5]
list_b = list_a
list_a[0] = 7
print id(list_a), id(list_b) # they have same id

Use List Slice to Copy

You can use list_b = list_a[:]. When the first index are omitted, it means beginning of list. When the ending index is omitted, it means end of list. Here's a test:

# -*- coding: utf-8 -*-
# python
list_a = [3,4,5]
list_b = list_a[:]

print id(list_a) == id(list_b) # prints “false”. They are different objects
print list_a == list_b # prints “true”.

Use “.extend()” to Copy

# -*- coding: utf-8 -*-
# python
list_a = [3, 4, 5]
list_b = []
list_b.extend(list_a)

print id(list_a) == id(list_b) # prints “false”

print list_a == list_b # prints “true”.

Use “list()” to Copy

A even better way is using “list()”.

# -*- coding: utf-8 -*-
# python
list_a = [3, 4, 5]
list_b = list(list_a)

print id(list_a) == id(list_b) # prints “false”

print list_a == list_b # prints “true”.

Copying Nested List

If you need to copy a nested list, you can use the module “copy”. Any of {slice, “.extend()”, “list()”} does not work. They only create a copy on the 0th level (called shallow copy). Elements of the list are copied by reference. Example:

# -*- coding: utf-8 -*-
# python
list_a = [[3, 4], [5, 6, [7, 8]]]
list_b = list(list_a)

list_a[0][1] = 9

print list_a # prints [[3, 9], [5, 6, [7, 8]]]
print list_b # prints [[3, 9], [5, 6, [7, 8]]]

Use Copy Module to Make a Truely independent Copy of a List

# -*- coding: utf-8 -*-
# python
import copy

list_a = [[3, 4], [5, 6, [7, 8]]]
list_b = copy.deepcopy(list_a)

list_a[0][1] = 9

print list_a # prints [[3, 9], [5, 6, [7, 8]]]
print list_b # prints [[3, 4], [5, 6, [7, 8]]]

Popular posts from this blog

Browser User Agent Strings 2012

11 Years of Writing About Emacs

does md5 creates more randomness?