• 【阿里云训练营】python查漏补缺 1


    文章来自:微信公众号【机器学习炼丹术】。
    有问题疑惑,或者想交流交朋友的可以加个人微信:cyx645016617
    参考目录:

    1 注释

    • 在 Python 中,# 表示注释,作用于整行。
    • ''' ''' 或者 """ """ 表示区间注释,在三引号之间的所有内容被注释
      【例子】单行注释
    # 这是一个注释
    '''
    这是多行注释,用三个单引号
    这是多行注释,用三个单引号
    这是多行注释,用三个单引号
    '''
    

    2 is 与 ==

    a = "hello"
    b = "hello"
    print(a is b, a == b)  # True True
    
    a = ["hello"]
    b = ["hello"]
    print(a is b, a == b)  # False True
    

    注意:

    • is, is not 对比的是两个变量的内存地址
    • ==, != 对比的是两个变量的值
    • 比较的两个变量,指向的都是地址不可变的类型(str等),那么is,is not 和 ==,!= 是完全等价的。
    • 对比的两个变量,指向的是地址可变的类型(list,dict,tuple等),则两者是有区别的。

    3 运算优先级

    • 一元运算符优于二元运算符。例如3 ** -2等价于3 ** (-2)
    • 先算术运算,后移位运算,最后位运算。例如 1 << 3 + 2 & 7等价于 (1 << (3 + 2)) & 7
    • 逻辑运算最后结合。例如3 < 4 and 4 < 5等价于(3 < 4) and (4 < 5)

    4 查找所有属性和方法

    利用dir()方法,下面查找int这个类型的属性和方法

    b = dir(int)
    print(b)
    
    # ['__abs__', '__add__', '__and__', '__bool__', '__ceil__', '__class__',
    # '__delattr__', '__dir__', '__divmod__', '__doc__', '__eq__',
    # '__float__', '__floor__', '__floordiv__', '__format__', '__ge__',
    # '__getattribute__', '__getnewargs__', '__gt__', '__hash__',
    # '__index__', '__init__', '__init_subclass__', '__int__', '__invert__',
    # '__le__', '__lshift__', '__lt__', '__mod__', '__mul__', '__ne__',
    # '__neg__', '__new__', '__or__', '__pos__', '__pow__', '__radd__',
    # '__rand__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__',
    # '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__',
    # '__round__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__',
    # '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__',
    # '__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__',
    # 'bit_length', 'conjugate', 'denominator', 'from_bytes', 'imag',
    # 'numerator', 'real', 'to_bytes']
    

    其中有一个bit_length,找到一个整数的二进制表示,再返回其长度。

    a = 1031
    print(bin(a))  # 0b10000000111
    print(a.bit_length())  # 11
    

    5 type和isinstance3

    • type() 不会认为子类是一种父类类型,不考虑继承关系。
    • isinstance() 会认为子类是一种父类类型,考虑继承关系。

    6 位运算

    操作符 名称 示例
    ~ 按位取反 ~4
    & 按位与 4 & 5
    | 按位或 4 | 5
    ^ 按位异或 4 ^ 5
    << 左移 4 << 2
    >> 右移 4 >> 2
    print(bin(4))  # 0b100
    print(bin(5))  # 0b101
    print(bin(~4), ~4)  # -0b101 -5
    print(bin(4 & 5), 4 & 5)  # 0b100 4
    print(bin(4 | 5), 4 | 5)  # 0b101 5
    print(bin(4 ^ 5), 4 ^ 5)  # 0b1 1
    print(bin(4 << 2), 4 << 2)  # 0b10000 16
    print(bin(4 >> 2), 4 >> 2)  # 0b1 1
    

    6.1 原码、反码和补码

    二进制有三种不同的表示形式:原码、反码和补码,计算机内部使用补码来表示

    原码:就是其二进制表示(注意,有一位符号位)。

    00 00 00 11 -> 3
    10 00 00 11 -> -3
    

    反码:正数的反码就是原码,负数的反码是符号位不变,其余位取反(对应正数按位取反)。

    00 00 00 11 -> 3
    11 11 11 00 -> -3
    

    补码:正数的补码就是原码,负数的补码是反码+1。

    00 00 00 11 -> 3
    11 11 11 01 -> -3
    

    符号位:最高位为符号位,0表示正数,1表示负数。在位运算中符号位也参与运算。

    6.2 按位运算

    • 按位非操作 ~
    ~ 1 = 0
    ~ 0 = 1
    

    ~num的补码中的 0 和 1 全部取反(0 变为 1,1 变为 0)有符号整数的符号位在 ~ 运算中同样会取反。

    00 00 01 01 -> 5
    ~
    ---
    11 11 10 10 -> -6
    
    11 11 10 11 -> -5
    ~
    ---
    00 00 01 00 -> 4
    
    • 按位与操作 &
    1 & 1 = 1
    1 & 0 = 0
    0 & 1 = 0
    0 & 0 = 0
    

    只有两个对应位都为 1 时才为 1

    00 00 01 01 -> 5
    &
    00 00 01 10 -> 6
    ---
    00 00 01 00 -> 4
    
    • 按位或操作 |
    1 | 1 = 1
    1 | 0 = 1
    0 | 1 = 1
    0 | 0 = 0
    

    只要两个对应位中有一个 1 时就为 1

    00 00 01 01 -> 5
    |
    00 00 01 10 -> 6
    ---
    00 00 01 11 -> 7
    
    • 按位异或操作 ^
    1 ^ 1 = 0
    1 ^ 0 = 1
    0 ^ 1 = 1
    0 ^ 0 = 0
    

    只有两个对应位不同时才为 1

    00 00 01 01 -> 5
    ^
    00 00 01 10 -> 6
    ---
    00 00 00 11 -> 3
    

    异或操作的性质:满足交换律和结合律

    A: 00 00 11 00
    B: 00 00 01 11
    
    A^B: 00 00 10 11
    B^A: 00 00 10 11
    
    A^A: 00 00 00 00
    A^0: 00 00 11 00
    
    A^B^A: = A^A^B = B = 00 00 01 11
    
    • 按位左移操作 <<

    num << inum的二进制表示向左移动i位所得的值。

    00 00 10 11 -> 11
    11 << 3
    ---
    01 01 10 00 -> 88 
    
    • 按位右移操作 >>

    num >> inum的二进制表示向右移动i位所得的值。

    00 00 10 11 -> 11
    11 >> 2
    ---
    00 00 00 10 -> 2 
    

    6.3 利用位运算实现快速计算

    通过 <<>> 快速计算2的倍数问题。

    n << 1 -> 计算 n*2
    n >> 1 -> 计算 n/2,负奇数的运算不可用
    n << m -> 计算 n*(2^m),即乘以 2 的 m 次方
    n >> m -> 计算 n/(2^m),即除以 2 的 m 次方
    1 << n -> 2^n
    

    通过 ^ 快速交换两个整数。
    通过 ^ 快速交换两个整数。

    a ^= b
    b ^= a
    a ^= b
    

    通过 a & (-a) 快速获取a的最后为 1 位置的整数。

    00 00 01 01 -> 5
    &
    11 11 10 11 -> -5
    ---
    00 00 00 01 -> 1
    
    00 00 11 10 -> 14
    &
    11 11 00 10 -> -14
    ---
    00 00 00 10 -> 2
    

    6.4 利用位运算实现整数集合

    一个数的二进制表示可以看作是一个集合(0 表示不在集合中,1 表示在集合中)。

    比如集合 {1, 3, 4, 8},可以表示成 01 00 01 10 10 而对应的位运算也就可以看作是对集合进行的操作。

    元素与集合的操作:

    a | (1<<i)  -> 把 i 插入到集合中
    a & ~(1<<i) -> 把 i 从集合中删除
    a & (1<<i)  -> 判断 i 是否属于该集合(零不属于,非零属于)
    

    集合之间的操作:

    a 补   -> ~a
    a 交 b -> a & b
    a 并 b -> a | b
    a 差 b -> a & (~b)
    

    注意:整数在内存中是以补码的形式存在的,输出自然也是按照补码输出。

    【例子】C#语言输出负数。

    class Program
    {
        static void Main(string[] args)
        {
            string s1 = Convert.ToString(-3, 2);
            Console.WriteLine(s1); 
            // 11111111111111111111111111111101
            
            string s2 = Convert.ToString(-3, 16);
            Console.WriteLine(s2); 
            // fffffffd
        }
    }
    

    【例子】 Python 的bin() 输出。

    print(bin(3))  # 0b11
    print(bin(-3))  # -0b11
    
    print(bin(-3 & 0xffffffff))  
    # 0b11111111111111111111111111111101
    
    print(bin(0xfffffffd))       
    # 0b11111111111111111111111111111101
    
    print(0xfffffffd)  # 4294967293
    
    0b11
    -0b11
    0b11111111111111111111111111111101
    0b11111111111111111111111111111101
    4294967293
    

    是不是很颠覆认知,我们从结果可以看出:

    • Python中bin一个负数(十进制表示),输出的是它的原码的二进制表示加上个负号,巨坑。
    • Python中的整型是补码形式存储的。
    • Python中整型是不限制长度的不会超范围溢出。

    所以为了获得负数(十进制表示)的补码,需要手动将其和十六进制数0xffffffff进行按位与操作,再交给bin()进行输出,得到的才是负数的补码表示。

    人不可傲慢。
  • 相关阅读:
    C#学习(四)
    C#学习(三)
    sqlserver基本操作
    ado.net(1)
    wpf的学习日志(一)
    C#学习(二)
    三大范式
    存储过程
    事务
    范文模板
  • 原文地址:https://www.cnblogs.com/PythonLearner/p/13617076.html
Copyright © 2020-2023  润新知