6. Copy()
通过shallow或deep copy语法提供复制对象的函数操作。
shallow和deep copying的不同之处在于对于混合型对象的操作(混合对象是包含了其他类型对象的对象,例如list或其他类实例)。
1.对于shallow copy而言,它创建一个新的混合对象,并且将原对象中其他对象的引用插入新对象。
2.对于deep copy而言,它创建一个新的对象,并且递归地复制源对象中的其他对象并插入新的对象中。
普通的赋值操作知识简单的将心变量指向源对象。
import copy
a = [1,2,3]
b = [4,5]
c = [a,b]
# Normal Assignment
d = c
print id(c) == id(d) # True - d is the same object as c
print id(c[0]) == id(d[0]) # True - d[0] is the same object as c[0]
# Shallow Copy
d = copy.copy(c)
print id(c) == id(d) # False - d is now a new object
print id(c[0]) == id(d[0]) # True - d[0] is the same object as c[0]
# Deep Copy
d = copy.deepcopy(c)
print id(c) == id(d) # False - d is now a new object
print id(c[0]) == id(d[0]) # False - d[0] is now a new object
shallow copy (copy())操作创建一个新的容器,其包含的引用指向原对象中的对象。
deep copy (deepcopy())创建的对象包含的引用指向复制出来的新对象。
复杂的例子:
假定我有两个类,名为Manager和Graph,每个Graph包含了一个指向其manager的引用,而每个Manager有一个指向其管理的Graph的集合,现在我们有两个任务需要完成:
1) 复制一个graph实例,使用deepcopy,但其manager指向为原graph的manager。
2) 复制一个manager,完全创建新manager,但拷贝原有的所有graph。
import weakref, copy
class Graph(object):
def __init__(self, manager=None):
self.manager = None if manager is None else weakref.ref(manager)
def __deepcopy__(self, memodict):
manager = self.manager()
return Graph(memodict.get(id(manager), manager))
class Manager(object):
def __init__(self, graphs=[]):
self.graphs = graphs
for g in self.graphs:
g.manager = weakref.ref(self)
a = Manager([Graph(), Graph()])
b = copy.deepcopy(a)
if [g.manager() is b for g in b.graphs]:
print True # True
if copy.deepcopy(a.graphs[0]).manager() is a:
print True # True
7. Pprint()
Pprint模块能够提供比较优雅的数据结构打印方式,如果你需要打印一个结构较为复杂,层次较深的字典或是JSON对象时,使用Pprint能够提供较好的打印结果。
假定你需要打印一个矩阵,当使用普通的print时,你只能打印出普通的列表,不过如果使用pprint,你就能打出漂亮的矩阵结构
如果
import pprint
matrix = [ [1,2,3], [4,5,6], [7,8,9] ]
a = pprint.PrettyPrinter(width=20)
a.pprint(matrix)
# [[1, 2, 3],
# [4, 5, 6],
# [7, 8, 9]]
额外的知识
一些基本的数据结构
1. 单链链表
class Node:
def __init__(self):
self.data = None
self.nextNode = None
def set_and_return_Next(self):
self.nextNode = Node()
return self.nextNode
def getNext(self):
return self.nextNode
def getData(self):
return self.data
def setData(self, d):
self.data = d
class LinkedList:
def buildList(self, array):
self.head = Node()
self.head.setData(array[0])
self.temp = self.head
for i in array[1:]:
self.temp = self.temp.set_and_return_Next()
self.temp.setData(i)
self.tail = self.temp
return self.head
def printList(self):
tempNode = self.head
while(tempNode!=self.tail):
print(tempNode.getData())
tempNode = tempNode.getNext()
print(self.tail.getData())
myArray = [3, 5, 4, 6, 2, 6, 7, 8, 9, 10, 21]
myList = LinkedList()
myList.buildList(myArray)
myList.printList()
2. 用Python实现的普林姆算法
译者注:普林姆算法(Prims Algorithm)是图论中,在加权连通图中搜索最小生成树的算法。
from collections import defaultdict
from heapq import heapify, heappop, heappush
def prim( nodes, edges ):
conn = defaultdict( list )
for n1,n2,c in edges:
conn[ n1 ].append( (c, n1, n2) )
conn[ n2 ].append( (c, n2, n1) )
mst = []
used = set( nodes[ 0 ] )
usable_edges = conn[ nodes[0] ][:]
heapify( usable_edges )
while usable_edges:
cost, n1, n2 = heappop( usable_edges )
if n2 not in used:
used.add( n2 )
mst.append( ( n1, n2, cost ) )
for e in conn[ n2 ]:
if e[ 2 ] not in used:
heappush( usable_edges, e )
return mst
#test
nodes = list("ABCDEFG")
edges = [ ("A", "B", 7), ("A", "D", 5),
("B", "C", 8), ("B", "D", 9), ("B", "E", 7),
("C", "E", 5),
("D", "E", 15), ("D", "F", 6),
("E", "F", 8), ("E", "G", 9),
("F", "G", 11)]
print "prim:", prim( nodes, edges )
总结
如果想了解更多地数据结构信息请参阅相关文档。谢谢阅读。