一、变量、运算符与数据类型
1.变量与赋值
1).变量
能存储计算结果和表示值
变量起名的规范:
- 变量名可以包括字母、数字、下划线、但变量名不能以数字开头。
- Python 变量名是大小写敏感的,foo != Foo。
在使用变量之前,需要对其先赋值。
2).赋值
语法:a = 3
- python中一切数据皆为对象,譬如 3 是一个int类型的对象,一个对象不能被覆盖或直接摧毁
- python中的变量是存储在内存中数据的引用。
- python的赋值是更新了数据的指向。等号左面的变量名更像一个标签,指向内存中存储的数据。当一个变量名被赋予新的值,python便会开辟新内存存储新的值,并将变量名重新指向新的值,而不是指针不变,原值被新值覆盖。
b = 3
b = b + 5
print(b)
'''
8
'''
python在内存中的活动:
可以说python开辟新内存空间的原因是原数据对象不可以被覆盖。
但是当修改列表中的元素时,却直接在原数据上进行修改,当打印指向该列表元素的所有变量时,都会得到修改后的数据
a = [1, 2, 3]
b = a
b[0] = 1024
print(a)
'''
[1024, 2, 3]
'''
python内存中的活动:
令b[0] = 1024,1024虽是一个对象,但它并没有试图覆盖b
所指向的对象,而是对该对象的第一个元素进行修改。修改,而不是覆盖,所以它可以原对象进行操作,而不是令 b
指向修改后的对象。
所在第四行输出的 a
所指向的列表也发生了变化。
2.print()函数输出
- 将对象以字符串表示的方式格式化输出到流文件对象file里。其中所有非关键字参数都按
str()
方式进行转换为字符串输出; - 关键字参数
sep
是实现分隔符,比如多个参数输出时想要输出中间的分隔字符; - 关键字参数
end
是输出结束时的字符,默认是换行符\n
; - 关键字参数
file
是定义流输出的文件,可以是标准的系统输出sys.stdout
,也可以重定义为别的文件; - 关键字参数
flush
是立即把内容输出到流文件,不作缓存。
二、运算符
1.算术运算符
符 | 名称 | 示例 |
---|---|---|
+ | 加 | 1 + 1 |
- | 减 | 2 - 1 |
* | 乘 | 3 * 4 |
/ | 除 | 3 / 4 |
// | 整除(地板除) | 3 // 4 |
% | 取余 | 3 % 4 |
** | 幂 | 2 ** 3 |
print(3/4) #真除法
print(3//4) #除法取整商,向下取整
print(3%4) #除法取余数,字符串格式化
print(3**4) #幂运算
#注意:% 既可以用于取余,也可以用于字符串格式化
扩展:%在格式化中的用法
格式化符号 | 说明 |
---|---|
%c | 转换成字符(ASCII 码值,或者长度为一的字符串) |
%r | 优先用repr()函数进行字符串转换 |
%s | 优先用str()函数进行字符串转换 |
%d / %i | 转成有符号十进制数 |
%u | 转成无符号十进制数 |
%o | 成无符号八进制数 |
%x / %X | 转成无符号十六进制数(x / X 代表转换后的十六进制字符的大小写) |
%e / %E | 转成科学计数法(e / E控制输出e / E) |
%f / %F | 转成浮点数(小数部分自然截断) |
%g / %G | %e和%f / %E和%F 的简写 |
%% | 输出% (格式化字符串里面包括百分号,那么必须使用%%) |
2.比较运算符
操作符 | 名称 | 示例 |
---|---|---|
> | 大于 | 2 > 1 |
>= | 大于等于 | 2 >= 4 |
< | 小于 | 1 < 2 |
<= | 小于等于 | 5 <= 2 |
== | 等于 | 3 == 4 |
!= | 不等于 | 3 != 5 |
3.逻辑运算符
操作符 | 名称 | 示例 |
---|---|---|
and | 与 | (3 > 2) and (3 < 5) |
or | 或 | (1 > 3) or (9 < 2) |
not | 非 | not (2 > 1) |
4.位运算符
(后面位运算的时候会细分)
操作符 | 名称 | 示例 |
---|---|---|
~ | 按位取反 | ~4 |
& | 按位与 | 4 & 5 |
` | ` | 按位或 |
^ | 按位异或 | 4 ^ 5 |
<< | 左移 | 4 << 2 |
>> | 右移 | 4 >> 2 |
5.三元运算符
6.其他运算符
操作符 | 名称 | 示例 |
---|---|---|
in | 存在 | 'A' in ['A', 'B', 'C'] |
not in | 不存在 | 'h' not in ['A', 'B', 'C'] |
is | 是 | "hello" is "hello" |
is not | 不是 | "hello" is not "hello" |
*7运算符的优先级
运算符 | 描述 |
---|---|
** | 指数(最高优先级) |
~+- | 按位翻转,一元加号和减号 |
* / % // | 乘,除,取模和取整除) |
+ - | 加法减法 |
>> << | 右移,左移运算符 |
& | 位‘AND’ |
^| | 位运算符 |
<=<>>= | 比较运算符 |
<>==!= | 等于运算符 |
=%=/=//=-=+==*= | 赋值运算符 |
is is not | 身份运算符 |
in not in | 成员运算符 |
not and or | 逻辑运算符 |
三、数据类型
1.分类:
类型 | 名称 | 示例 |
---|---|---|
int | 整型 <class 'int'> | -876, 10 |
float | 浮点型<class 'float'> | 3.149, 11.11 |
bool | 布尔型<class 'bool'> | True, False |
2.常用方法:
四、位运算
1.原码、反码和补码
原码、反码和补码时二进制的三种不同表现形式,计算机内部使用补码来表示。
符号位:最高位为符号位,0表示正数,1表示负数。在位运算中符号位也参与运算。红字表示
1).原码
就是其二进制表示(有一位符号位)。
数值 | 符号位 | 数值位 | 原码(符号位+数值位) |
5 | 0 | 0000101 | 00000101 |
-5 | 1 | 0000101 | 10000101 |
2).反码
正数的反码就是原码,负数的反码是符号位不变,其余位取反(对应正数按位取反)。
数值 | 符号位 | 数值位 | 反码 |
5 | 0 | 0000101 | 00000101 |
-5 | 1 | 1111010 | 11111010 |
3).补码
正数的补码就是原码,负数的补码是反码+1。
数值 | 符号位 | 数值位 | 补码 |
5 | 0 | 0000101 | 00000101 |
-5 | 1 | 1111011 | 11111011 |
4).注意事项
- 整数在内存中是以补码的形式存在的,输出自然也是按照补码输出
- Python中
bin
一个负数(十进制表示),输出的是它的原码的二进制表示加负号,并非其原本的二进制形式 - Python中的整型是补码形式存储的。
- Python中整型是不限制长度的不会超范围溢出。
所以为了获得负数(十进制表示)的补码,需要手动将其和十六进制数0xffffffff
进行按位与操作,再交给bin()
进行输出,得到的才是负数的补码表示。
print(bin(-8 & 0xffffffff)) '''0b11111111111111111111111111111000'''
2.按位运算
1).按位非操作(~)
~ 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
'''
2).按位与操作(&)
只有两个对应位都为 1 时才为 1
'''
1 & 1 = 1
1 & 0 = 0
0 & 1 = 0
0 & 0 = 0
00 00 01 01 -> 5
&
00 00 01 10 -> 6
---
00 00 01 00 -> 4
'''
3).按位或操作(|)
只要两个对应位中有一个 1 时就为 1
'''
1 | 1 = 1
1 | 0 = 1
0 | 1 = 1
0 | 0 = 0
00 00 01 01 -> 5
|
00 00 01 10 -> 6
---
00 00 01 11 -> 7
'''
4).按位异或操作(^)
只有两个对应位不同时才为 1
'''
1 ^ 1 = 0
1 ^ 0 = 1
0 ^ 1 = 1
0 ^ 0 = 0
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
'''
5).按位移动操作(<<和>>)
- 按位左移操作 <<
num << i
将num
的二进制表示向左移动i
位所得的值。
'''
00 00 10 11 -> 11
11 << 3
---
01 01 10 00 -> 88
'''
- 按位右移操作 >>
num >> i
将num
的二进制表示向右移动i
位所得的值。
'''
00 00 10 11 -> 11
11 >> 2
---
00 00 00 10 -> 2
'''
3.位运算的快速计算
1).通过 <<
,>>
快速计算2的倍数问题。
解释:移位即做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
'''
print(8 << 1,"=8*2^1") #16 =8*2^1
print(8 << 2,"= 8*2^2") #32 = 8*2^2
print(8 >> 2,"= 8/2^2") #2 = 8/2^2
print(1 << 3,"=1*2^3") #8 =1*2^3
2).通过 ^
快速交换两个整数。
解释:
^为异或,特征是只有两个对应位不同时才为 1,故可以得到:
- a^a = 0
- a^0 = a
所以有:
a = a^(b^b) = (a^b)^b
b = b^(a^a) = (b^a)^a
因此:
a ^ = b → a = a^b
b ^ = a → b = b^a = b^(a^b) = a^(b^b) = a
a ^ = b → a = a^b = (a^b)^a = b^(a^a) = b
'''
a ^= b
b ^= a
a ^= b
'''
a = 1
b = 2
a = a^b
b = b^a
a = a^b
print("a为",a,"\nb为",b)
#a为 2
#b为 1
3). a & (-a)
快速获取a
的最后为 1 位置的整数。
python中正数是原码的形式,负数是补码的形式
&与操作是只有两个对应位都为 1 时才为 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
'''
4.利用位运算实现整数集合
一个数的二进制表示可以看作是一个集合(0 表示不在集合中,1 表示在集合中)。
比如集合 {1, 3, 4, 8}
,可以表示成 01 00 01 10 10,
由右到左的位数对应数字0到9,集合中数字对应的位数为1,其余为0。对应的位运算也就可以看作是对集合进行的操作。
元素与集合的操作:
'''
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)
'''
注意:整数在内存中是以补码的形式存在的,输出自然也是按照补码输出