学习链接: 变量、运算符与数据类型和位运算。
一、基础
1.1 注释
- 单行注释
#
- 多行注释
''' '''
或者""" """
1.2 运算符
- 算术运算符
操作符 | 名称 |
---|---|
+ | 加 |
- | 减 |
* | 乘 |
/ | 除(真除法:不管操作数的类型,都返回包含小数的结果) |
// | 整除(对于整数执行截断除法,对于浮点数执行浮点除法) |
% | 取余 |
** | 幂 |
- 比较运算符
操作符 | 名称 |
---|---|
> | 大于 |
>= | 大于等于 |
< | 小于 |
<= | 小于等于 |
== | 等于 |
!= | 不等于 |
- 逻辑运算符
操作符 | 名称 |
---|---|
and | 与 |
or | 或 |
nit | 非 |
- 位运算符
操作符 | 名称 |
---|---|
~ | 按位取反 |
& | 按位与 |
| | 按位或 |
^ | 按位异或 |
- 移位符
操作符 | 名称 |
---|---|
<< | 左移 |
>> | 右移 |
- 其他操作符
操作符 | 名称 |
---|---|
in | 存在 |
not in | 不存在 |
is | 是 |
is not | 不是 |
注:
is, is not 对比的是两个变量的内存地址,= =, != 对比的是两个变量的值。则比较的两个变量,指向的都是地址不可变的类型(str等),那么is,is not 和 ==,!= 是完全等价的;指向的是地址可变的类型(list,dict,tuple等),则两者是有区别的。
- 运算符的优先级
一元运算符优于二元运算符。例如3 * -2
等价于3 * (-2)
。
先算术运算,后移位运算,后位运算,逻辑运算最后结合。
1.3 变量
变量的命名:
- 变量名只能包含字母、数字和下划线,只能以字母或数字打头
- 变量名对大小写敏感
- 不要将Python关键字和函数名作为变量名,即不要使用Python保留用于特殊用途的单词
1.4 数据类型
-
基本数据类型:
类型 名称 示例 int 整型 -876、10 float 浮点型 3.149、11.0 bool 布尔型 True、False 容器数据类型:
类型 名称 示例 str 字符串 ‘20’、‘abc’ tuple 元组 (1,) list 列表 [1,‘a’] dict 字典 {‘a’ :1 } set 集合 set(1,2 ) -
获取类型信息
type(object)
、isinstance(object, classinfo)
In:type(1) Out:<class 'int'> In:isinstance(1, int) Out:True
注:type() 不会认为子类是一种父类类型,不考虑继承关系。
isinstance() 会认为子类是一种父类类型,考虑继承关系。 -
类型转换
转换为整型int(x, base=10)
转换为字符型str(x)
转换为浮点型float(x)
1.5 输出print()函数
print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)
将对象以字符串表示的方式格式化输出到流文件对象file里。其中所有非关键字参数都按str()方式进行转换为字符串输出;
合理使用单双引号可以避免使用转义字符;
关键字参数sep是实现分隔符,比如多个参数输出时想要输出中间的分隔字符;
关键字参数end是输出结束时的字符,默认是换行符\n;
关键字参数file是定义流输出的文件,可以是标准的系统输出sys.stdout,也可以重定义为别的文件;
关键字参数flush是立即把内容输出到流文件,不作缓存。
In:print('Hello \"World')
print('Hello "World')
Out:Hello "World
1.6 位运算
1.6.1 原码、反码和补码
二进制有三种不同的表示形式:原码、反码和补码,其中最高位是符号位(正数0,负数),在位运算中符号位也参与运算。计算机内部使用补码来表示。
原码:就是二进制表示
反码:正数的反码就是原码,负数的反码是符号位不变,其余位取反。
补码:正数的补码就是原码,负数的补码是反码+1。
3 -> 00 00 00 11 #3的原码、反码、补码
-3 -> 10 00 00 11 #-3的原码
11 11 11 00 #-3的反码
11 11 11 01 #-3的补码
1.6.2 位运算
1.按位非
~1 = 0
~0 = 1
In:~5 #原码00000101 补码00000101 取反11111010
Out:-6 #11111010是-6的补码
2.按位与
-
两个对应位都为1时才为1
1 & 1 = 1
1 & 0 = 0
0 & 1 = 0
0 & 0 = 0In:5 & 6 #00000101 & 00000110 Out:4 #00000100
3.按位或
-
只要两个对应位中有一个为1就是1
1 | 1 = 1
1 | 0 = 1
0 | 1 = 1
0 | 0 = 0In:5 | 6 #00000101 | 00000110 Out:7 #00000111
4.按位异或
-
只有两个对应位不同时才为1
1 ^ 1 = 0
1 ^ 0 = 1
0 ^ 1 = 1
0 ^ 0 = 0In:5 ^ 6 #00000101 ^ 00000110 Out:3 #00000011
-
异或操作的性质:
满足交换律 A ^ B = B ^ A
满足结合律 A ^ B ^ A = A ^ A ^ B = B
A ^ A = 0
A ^ 0 = A
5.按位移位操作
-
按位左移<<
num << i 将num的二进制表示向左移动 i 位所得的值。In:11 << 3 #00001011 Out:88 #01011000
-
按位右移>>
num >> i 将num的二进制表示向右移动 i 位所得的值。
1.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 位置的整数。
In:5 & -5 #00000101 & 11111011 Out:1
1.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)
练习题
1.怎样对python中的代码进行注释?
#这是一行注释
'''
这是多行注释
这是多行注释
这是多行注释
'''
2.python有哪些运算符,这些运算符的优先级是怎样的?
算数运算->移位运算->位运算->逻辑运算
3.python 中 is, is not 与 ==, != 的区别是什么?
is, is not 对比的是两个变量的内存地址,= =, != 对比的是两个变量的值。(id()函数返回一个身份标识符,可以理解为一个变量的内存地址)
4.python 中包含哪些数据类型?这些数据类型之间如何转换?
int('721')
float(10)
str(10+10)
5.leetcode 习题 136. 只出现一次的数字
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
尝试使用位运算解决此题。
题目说明:
"""
Input file
example1: [2,2,1]
example2: [4,1,2,1,2]
Output file
result1: 1
result2: 4
"""
class Solution:
def singleNumber(self, nums: List[int]) -> int:
# your code here
temp = 0
for num in nums:
temp ^= num
return temp