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]]))
    

    待续

  • 相关阅读:
    iOS中Zbar二维码扫描的使用
    SOJ 1135. 飞跃原野
    SOJ 1048.Inverso
    SOJ 1219. 新红黑树
    SOJ 1171. The Game of Efil
    SOJ 1180. Pasting Strings
    1215. 脱离地牢
    1317. Sudoku
    SOJ 1119. Factstone Benchmark
    soj 1099. Packing Passengers
  • 原文地址:https://www.cnblogs.com/MTandHJ/p/10528182.html
Copyright © 2011-2022 走看看