zoukankan      html  css  js  c++  java
  • Python Revisited (变量)

    @

    首先,需要指出的是,Python的变量采用的是对象绑定的方式,在程序运行过程中,要时刻注意,对象的变化和共享。

    =

    第一种情况 = 右边是值 这种情况并不会产生歧义

    a = 1
    a = '1'
    a = [1]
    a = {1:'1'}
    

    第二种情况 = 右边是对象引用(变量——个人的说法)

    b = 1
    a = b
    

    当变量(b)为固定类型——float, int, str, frozenset, tuple等等都是没关系的。
    当变量为可变的数据类型——dict, list, set, 就存在风险。

    b = [1, 2, 3]
    a = b
    a[0] = 4
    a, b # ([4, 2, 3], [4, 2, 3])
    

    浅拷贝

    b = a[ : ] #a 为列表 这种情况是浅拷贝 比=略强

    a = [1, ['2', 5], 3]
    b = a[:]
    a[0] = 2
    b[1][0] = 'two'
    a, b #([2, ['two', 5], 3], [1, ['two', 5], 3])
    

    以下复制的方式都是浅拷贝:
    .copy()
    dict()
    list()
    set()
    a[:]

    深拷贝`

    a = [1, ['2', 5], 3]
    b = copy.deepcopy(a)
    a[0] = 2
    b[1][0] = 'two'
    a, b #([2, ['2', 5], 3], [1, ['two', 5], 3])
    

    函数的默认参数为可变类型时 危险

    def append_if_even(x, lst=[]):  #从对象绑定的角度考虑,合情合理
        if x % 2 == 0:
            lst.append(x)
        print(lst)
    
    append_if_even(2) #[2]
    append_if_even(2) #[2, 2] 
    append_if_even(2) #[2, 2, 2]
    append_if_even(2) #[2, 2, 2, 2]
    
    

    全局变量与临时变量

    函数里面创建的变量属于临时变量,在这上面摔的跤太多了。

    global

    def remain():
        global REMAIN
        REMAIN = 3
    def sum_and_add(a, b):
        remain() #得执行一次
        return a + b + REMAIN
    sum_and_add(1, 2) # 6
    
    
    

    在函数里面进行复制

    就像在上面讲的,=只是赋值,在函数里面玩这种很容易就凉凉。

    def test(a):
    	b = a # a 属于 list  如果你不希望改变a的值可以采用 b= a[:] 如果是多重的可以考虑深拷贝
    	b.append(1)
    a = [1]
    test(a)
    a #[1, 1]
    
    

    再看一个例子

    def main():
        a = [1]
        print(id(a))
        ccc(a)
        print(id(a))
        print(a)
    def ccc(a):
        a= sorted(a)  #这一步令a指向了新的内存地址,所以下面对a操作都不会影响最初的a
        print(id(a))
        a.append(1)
        print(id(a))
        ccd(a)
    def ccd(a):
        a.append(1)
        print(id(a))
    main()    
    """
    2431712245320
    2431712245512
    2431712245512
    2431712245512
    2431712245320
    [1]
    """
    
    def main():
        a = [1]
        print(id(a))
        ccc(a)
        print(id(a))
        print(a)
    def ccc(a):
        a.sort()  #并没有改变a的指向,不过需要注意的是 [].sort() is None
        print(id(a))
        a.append(1)
        print(id(a))
        ccd(a)
    def ccd(a):
        a.append(1)
        print(id(a))
    main()    
    """
    2431712245384
    2431712245384
    2431712245384
    2431712245384
    2431712245384
    [1, 1, 1]
    """
    

    numpy里的bug?

    ndarray里面用id蛮奇怪的,list是都不一样的,同学说可能是沿袭了C。

    A = np.array([[1, 2], [3, 4]])
    print(id(A))
    for i in range(2):
        for j in range(2):
            print(id(A[i, j])) 	
    
    
    #2392090756480
    #2392073432760
    #2392073432760
    #2392073432760
    #2392073432760
    
    

    下面这个例子,符合我们的预期

    A = np.arange(4).reshape(2, 2)
    a = A[0,...]
    print(id(a[0]), id(A[0, 0]), id(A[1, 1]))
    a[0] = 999
    print(id(a[0]), id(a[1]), id(A[0, 0]), id(A[1, 1]))
    a, A
    
    #2392073432160 2392073432160 2392073432160
    #2392073432160 2392073432160 2392073432160 2392073432160
    #[121]:
    #(array([999,   1]), array([[999,   1],
    #        [  2,   3]]))
    

    下面的例子就不是了,为什么不改呢?

    A = np.arange(4).reshape(2, 2)
    a = A[np.array([[True, False], [False, True]])]
    #a = A[[0, 1], [0, 1] 同样不行
    print(id(a[0]), id(A[0, 0]), id(A[1, 1]))
    a[0] = 999
    print(id(a[0]), id(a[1]), id(A[0, 0]), id(A[1, 1]))
    a, A
    
    #2392073432064 2392073432064 2392073432064
    #2392073432064 2392073432064 2392073432064 2392073432064
    #(array([999,   3]), array([[0, 1],
    #        [2, 3]]))
    

    待续

  • 相关阅读:
    猴子得到一堆桃,当天吃了一半之后,又多吃了1个。以后每天,猴子都吃了剩余的一半桃子之>后,又多吃一个。在第10天,只剩下1个桃子。输出这堆桃最初有多少个。
    打印9 9乘法表
    尝试实现一个管理系统, 名字和电话号分别用两个列表存储 =======通讯录管理系统======= 1.增加姓名和手机 2.删除姓名 3.修改手机 4.查询所有用户 5.根据姓名查找手机号 6.退出
    求结果
    背景流动
    1
    zuoye
    假期 作业1220
    python1217作业
    pythonzuoye20181212
  • 原文地址:https://www.cnblogs.com/MTandHJ/p/10528182.html
Copyright © 2011-2022 走看看