Python由数据结构树引发的思考(可变对象/不可变对象,深拷贝/浅拷贝)

标签: 深拷贝浅拷贝 可变对象 不可变对象
7人阅读 评论(0) 收藏 举报
分类:

数据类型二叉树之前就有写过,我曾一直认为,因为Python没有指针操作,所有实现起来会有麻烦,应该会用数组插入数组的方法进行实现。然后进行了尝试:

class Node:
    date=None
    left=None
    right=None

class Tree:
    def __init__(self):
        self.Root=Node()
        self.index=0
    def Create_Tree(self,DateArray,ptr):
        print('index',self.index)
        print('date',DateArray[self.index])
        if DateArray[self.index]=='#':
            ptr.date='#'
            self.index+=1
            return
        ptr.date=DateArray[self.index]
        self.index+=1
        ptr.left=Node()
        ptr.right=Node()
        self.Create_Tree(DateArray,ptr.left)
        self.Create_Tree(DateArray,ptr.right)
    def display(self,ptr):
        if ptr.date=='#':
            print('#')
            return
        print(ptr.date)
        self.display(ptr.left)
        self.display(ptr.right)


if __name__=="__main__":
    x=Tree()
    dates="ab##c##"
    print(dates)
    x.Create_Tree(DateArray=dates,ptr=x.Root)
    x.display(x.Root)
    print("over")

‘#’字符为空节点判断标志,这里任然实现了通过前序遍历的方法创建树,但是值得思考的是这里:

self.Create_Tree(DateArray,ptr.left)
self.Create_Tree(DateArray,ptr.right)

这里将Node的左节点和右节点作为参数传输函数中,如果按照C/C++的逻辑应该是拷贝一份变量传入,所以后面的赋值都没有意义,这里就存在了可变对象和不可变对象的问题。
再看一个例子:

class Node:
    date=None
    Next=None

def Fixed(ptr):
    print(id(ptr))
    ptr.date="test"
    ptr.Next=None
    print(id(ptr))

def Change(x):
    print('change',id(x))
    x=11
    print(id(x))
if __name__=="__main__":
    x=Node()
    x.date="fantasy"
    Fixed(x)
    print(x.date)
    c=22
    Change(c)
    print(c)

很清楚的知道,int类型的c通过函数修改其值需要加global所以,c不会改变
但是这里x通过函数属性被修改了,这两个对象在函数调用过程中地址均未发生改变,之所以会右这样的不同原因就在于int对象是不变对象,在c值被修改后吗,会发现c的地址也发生了改变。

**可变对象:**list,dict,set等,不会发生拷贝,直接对对象进行赋值。
**不可变对象:**int,float,string,tuple等,赋值时会重新开辟一段内存空间进行复制,然后变量再绑定到新的内存空间。

如果希望将对象最为参数传入函数并且不被修改,则需要进行拷贝,感觉就像人为的做了C/C++传参的操作,操作如下:

f __name__=="__main__":
    x=Node()
    x.date="fantasy"
    print('x',id(x))
    y=copy.copy(x)
    print('y',id(x))
    Fixed(y)
    print(x.date)

此时对象x就没有被函数改变,可以看到x和y地址已经不同。
这里出现疑问deepcopy和copy同时实现了对对象的拷贝工作,其区别在哪里。
copy仅拷贝当前对象,deepcopy则拷贝当前对象及其子对象,也就说deepcopy后的对象与拷贝对象不再想干,而浅拷贝对象的子对象任然会受到拷贝对象子对象的影响。

查看评论

可变对象 vs 不可变对象(Python)

Python 在 heap 中分配的对象分成两类:可变对象和不可变对象。所谓可变对象是指,对象的内容是可变的,例如 list。而不可变的对象则相反,表示其内容不可变。 不可变对象:int,string...
  • lanchunhui
  • lanchunhui
  • 2016年08月27日 22:27
  • 1042

Python学习笔记——可变类型&不可变类型&深拷贝&浅拷贝

可变类型&不可变类型可变类型:字典(dict),列表(list)不可变类型:数字(包括int,float等),字符串(str),元组(tuple)什么是可变&不可变?num = 100 print(i...
  • Leo_Coding
  • Leo_Coding
  • 2017年06月09日 21:28
  • 377

Python中可变对象和不可变对象

之前写了FPGrowth的代码,写得非常恶心,觉得和C语言、C++的工程文件很不相同。其中就有关于传引用、传值的疑问。截一段Leetcode的代码这题好像是Leetcode 93附近的一道 获得二叉树...
  • u013007900
  • u013007900
  • 2017年02月13日 12:56
  • 1099

Python学习笔记——可变对象和不可变对象

转载自:http://www.cnblogs.com/evening/archive/2012/04/11/2442788.html
  • taohuaxinmu123
  • taohuaxinmu123
  • 2014年09月02日 16:40
  • 14165

python学习之路——函数关于可变对象和不可变对象问题

可更改(mutable)与不可更改(immutable)对象 在 python 中,整数、字符串和 元组是不可更改的对象,而 列表,字典 等则是可以修改的对象。 不可变类型:变量赋值 a=5 后再...
  • eml_jw
  • eml_jw
  • 2017年05月04日 20:05
  • 434

python可变对象与不可变对象

不可变对象为int tupe str可变对象为list 以及 dict因为他们可以append.不用重新创建对象...
  • dzp443366
  • dzp443366
  • 2017年02月03日 21:44
  • 316

Python中的可变,不可变对象;值类型,引用类型;浅拷贝,深拷贝理解

可变对象,不可变对象,值类型,引用类型,浅拷贝,深拷贝。
  • github_34777264
  • github_34777264
  • 2017年12月31日 15:09
  • 89

Python拷贝对象(浅拷贝copy与深拷贝deepcopy)

先说一段废话。Python中的参数传递都是对象引用传递,这种方式相当于传值和传引用的一种综合。如果函数收到的是一个可变对象(比如字典或者列表)的引用,就能修改对象的原始值——相当于通过“传引用”来传递...
  • zhangqi_gsts
  • zhangqi_gsts
  • 2016年10月22日 00:17
  • 1084

Python中深拷贝与浅拷贝的区别:

Python中深拷贝与浅拷贝的区别:
  • u014745194
  • u014745194
  • 2017年04月20日 16:58
  • 2889

【Java深入】深拷贝与浅拷贝详解

1.拷贝的引入(1)引用拷贝创建一个指向对象的引用变量的拷贝。例1:Teacher teacher = new Teacher("Taylor",26); Teacher otherteacher =...
  • baiye_xing
  • baiye_xing
  • 2017年05月13日 11:12
  • 755
    个人资料
    持之以恒
    等级:
    访问量: 1万+
    积分: 545
    排名: 9万+
    百度统计

    load compelet