python基础(一):python直接赋值、深浅拷贝的理解

对python直接赋值、深浅拷贝的本来认识
直接赋值:是对象的引用(别名),赋值对象和被赋值对象都指向同一对象
浅拷贝:拷贝的父对象间相互独立。但是拷贝父对象,不会拷贝对象的内部的子对象
深拷贝: 拷贝对象中的每个元素,拷贝对象和原有对象不再有关系,两个是独立的对象

但是最近在一些例子中,遇到了疑惑的问题,思考的过程如下:

1.关于直接赋值(在链表中的应用)

a = [1, 2, 3, 4, ['a', 'b']] #原始对象
b = a                       #赋值,传对象的引用

在对链表等特殊的数据结构进行分析时,需要注意直接赋值的变量指向的对象。
(题目来源:203. 移除链表元素

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution(object):
    def removeElements(self, head, val):
        """
        :type head: ListNode
        :type val: int
        :rtype: ListNode
        """
        head_copy=head
        if not head:
            return None

        while head!=None and head.val==val:
            head=head.next

        while head_copy.next:
            if head_copy.next.val==val:
                head_copy.next=head_copy.next.next
            else:
                head_copy=head_copy.next

        return head

不解的点在于,head赋值给head_copy,两者是对同一对象的引用,所以两者指向的内容应该一致。
但是比如处理链表[7,7,7,7],val=7 经过以下代码,head链表已经为空了,但是head_copy依旧是[7,7,7,7]

        while head!=None and head.val==val:
            head=head.next

我的理解是,head指针本身在一次次往后移,但是链表中的内容始终没有发生变化,仍是[7,7,7,7],所以head_copy依旧是[7,7,7,7]。

但如果是例子[1,4,2,4],val=4.发挥作用的代码段如下。head_copy遇到指向节点的下一节点值为4时,会更改链表本身的连接,所以最后return head,返回的也是[1,2]

        head_copy=head
        
        while head_copy.next:
            if head_copy.next.val==val:
                head_copy.next=head_copy.next.next
            else:
                head_copy=head_copy.next

2.python浅拷贝

浅拷贝可以通过list 对列表进行浅拷贝,也可以通过copy函数。需要特别注意拷贝的父对象是独立的对象,但他们的子对象还是指向统一对象(是引用)

import copy
a = [1, 2, 3, 4] #原始对象
b = list(a)  # 可以通过list 对列表进行浅拷贝
c = copy.copy(a)            #对象拷贝,浅拷贝

比如对上面的代码,a列表中只有父对象没有子对象,所以a和b、c间完全独立,a的变化不会影响到b、c

import copy
a = [1, 2, 3, 4, ['a', 'b']] #原始对象
b = list(a)  # 可以通过list 对列表进行浅拷贝
c = copy.copy(a)            #对象拷贝,浅拷贝

但是对于a = [1, 2, 3, 4, [‘a’, ‘b’]]作为原始对象,a列表中有子对象[‘a’, ‘b’],当a中的父对象变化时,b、c不受影响;当a中的子对象变化时,b、c跟着变

a.append(5) 
#a = [1, 2, 3, 4, ['a', 'b'],5]
#b=[1, 2, 3, 4, ['a', 'b']]
#c=[1, 2, 3, 4, ['a', 'b']]
a[-1].append('c')
#a = [1, 2, 3, 4, ['a', 'b','c']]
#b=[1, 2, 3, 4, ['a', 'b','c']]
#c=[1, 2, 3, 4, ['a', 'b','c']]

还需要注意的是b、c之间的关系,当a中不包含子对象时,b、c间自然相互独立;当a中包含子对象时,需要非常当心b、c间也是互为浅拷贝的关系,b中子对象的变化会同时影响到a、c中的子对象。
总结来说就是,a、b、c之间是一个平等的关系,不管谁的子对象产生了变化,都会影响到另外两个变量。
因此在实际应用当中,要慎重使用浅拷贝。

3.python深度拷贝

理解起来最简单,就是一个完整的拷贝,拷贝之后拷贝对象中的每个元素相互独立。

import copy
a = [1, 2, 3, 4, ['a', 'b']] #原始对象
d = copy.deepcopy(a)        #对象拷贝,深拷贝
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值