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 )
總結
如果想了解更多地數據結構信息請參閱相關文檔。謝謝閱讀。