Python学习记录-02-运算符和表达式
1.运算符
1.1 加 [+]
就是实现两个对象相加,例子如下:
a=3
b=4
c='3'
d='e'
e=3.1
f=22.00
print(a+b)
print(c+d)
print(e+f)
输出:
7
3e
25.1
注意:做运算时,不能用整数加减字符串,即:
a=3
d='e'
print(a+d)
输出:
TypeError: unsupported operand type(s) for +: 'int' and 'str'
1.2 减 [-]
就是从一个数中减去另一个数字,如果第一个数不存在,则假定第一个数为0,例子如下:
a=3
b=4
c=-5.2
d=-3
print(a-b)
print(c-d)
输出:
-1
-2.2
1.3 乘 [*]
就给出数的乘积或者是字符串重复指定次数后的结果
a=3
b=4
c='c'
d=4
print(a*b)
print(c*d)
输出:
12
cccc
1.4 乘方 [**]
就是实现x^y 不过具体写为x**y
a=3
b=4
print(b**a) #等同于 4*4*4
输出:
64
1.5 除 [/]
实现x/y。x为分子,y为分母;
注:此处需要和 \ 区分开; \ 为转义序列
a=13
b=4
print(a/b)
输出:
3.25
1.6 整除 [//]
在除法的基础上,除完之后取整(只保留整数位)。x为分子,y为分母,
a=13
b=4
print(a//b)
输出:
3
1.7 取模 [%]
在除法的基础上,只保留余数,如:13÷4=3余1; 则:13%3=1
a=19
b=9
c=34
d=10
print(a%b)
print(c%d)
输出:
1
4
1.8 左移 [<<]
此处需要转换为二进制理解,比如3=11;4=100;5=101
之后需要知道,3=0000 0011;4=0000 0100;5=0000 0101
左移,可以理解为,把指定的数字,在“轴”上,数字的位,左移X位,举例如下:
a=3
b=2
print(a<<b) # 就是实现了3的二进制数字0000 0011,在数轴上,数字的位,往左边移动2位,变成 0000 1100;即变成了12
输出:
12 #12的二进制标识为0000 1100
额外测试:
a=4
b=3
print(a<<b) #即 0000 0100,里面的1向左移动3位,变为0010 0000,即32
输出:
32 #
1.9 右移 [>>]
此处何左移刚好相反
a=32
b=2
print(a>>b) #32=0010 0000,变为 0000 1000 即8
c=33
d=3
print(c>>d) #33=0010 0001,变为 0000 0100 即4
输出:
4
原因:
#原始: 0 0 1 0 0 0 0 1 (33)
↓ 右移 3 位
#第1步: 0 0 0 1 0 0 0 0 (16) ← 最右边的 1 掉了
#第2步: 0 0 0 0 1 0 0 0 (8) ← 又掉一个 0
#第3步: 0 0 0 0 0 1 0 0 (4) ← 又掉一个 0
#Python 的 `>>` 不是硬件层面的"固定位数补码移位",而是**高级语言封装的数学运算**:
#正数右移:挤掉右边,左边补 0,等于除以 2ⁿ 向下取整。
#那个被挤掉的 1,就像纸带打孔机剪掉的一截——没了,也不参与任何后续计算。
记忆点:
可以把数字看作一个条状的打孔带,无论左移还是右移,都是“打孔带”的整体移动。
注:左移的话,类似右边的0补充左边,且在python中,数字无限大,左移就是纯粹的乘法;右移动的话,右边就有1被“挤出去”的可能,即存在截断、丢弃。
kimi的解释中提到:
1.是因为python中,整数无限大,所以左移不会挤掉
33 << 3
# 0010 0001 → 0001 0000 1000 (264)
# 左边没有天花板,不会丢,位数直接变多
2.但是在C和python中
C 语言 (32位 int):
0010 0001 << 3
= 0001 0000 1000 ← 变成 9 位了,装不下!
最高位的 0 被丢弃,只保留低 32 位
1.10 按位与 [&] “两个全真才真”
对数字进行按位与操作。与操作也需要先把数字转为二进制理解。之后,2位同为1时,则运算输出1,否则输出为0
a=3 #3=0000 0011
b=5 #5=0000 1001
print(a&b) #上下两行,与运算之后为:0000 0001;即右起2、4位的与运算结果均为0
输出:
1
再来一个例子:
a=36 #36=0010 0100
b=25 #25=0001 1001
print(a&b) #上下两行,与运算之后为:0000 0000;
a=12 #12=0000 1100
b=6 # 6=0000 0110
print(a&b) #上下两行,与运算之后为:0000 0100;
输出:
0
4
1.11 按位或 [|] “有一个为真就真”
对数字进行按位或操作。与操作也需要先把数字转为二进制理解。之后,有1位为1时,则运算输出1,否则输出为0
a=3 #3=0000 0011
b=5 #5=0000 0101
print(a|b) #上下两行,或运算之后为:0000 0111;
输出:
7
1.12按位非 [~] “真变假,假变真,按位取反”
①对数字进行按位或操作。与操作也需要先把数字转为二进制理解。之后,有1位为0时,则运算输出1,否则输出为0。
②python中也给出了公式:~X=-(X+1)
按照上述3种方式,可以计算按位取反
但是,此时会有一个问题如下:
a=3,按照公式计算,~3=-4
但是,如果转为二进制之后,按位取反可能会这么做:
a=3 #3=0000 0011
#取反之后为:1111 1100;再转化为10进制时,为254,此时得到的结果和公式计算的-4就不一样了
原因:
陷入了误区。因为python中,数字是无限长的。
上述例子中,假设3是8位二进制数构成。
但实际在python中,原始3= .....000011,里面的0有无数个。
逐位取反之后,应该为 ~3=....1111100,有无数个1。
此处补充一个内容:
#正数:前面有无限个 0
#负数:前面有无限个 1
所以:....1111100肯定是一个负数;现在就是要求这个负数转为10进制是几?
根据下面原码、反码、补码的知识,我们可以知道,负数要想计算,必须转化为补码。
负数转为补码的规则为:反码+1
所以最终计算逻辑为:
....1111100为负数,转为反码得到:....00000011;反码+1得到:....00000100
即为-4
再次举例:
a=10
print(~a)
输出:
-11
解析:
方法1,调用公式:~10=-(10+1)
方法2:
10转为二进制为:....0000 1010
按位取反为: ....1111 0101 此时为负数,要想表示负数,需要把负数先取反,再加1
取反为: ....0000 1010
加1为: ....0000 1011
因为我们要表示一个负数,所以为 - 1011 ,即-11
继续举例:
a=-2
print(~a)
输出:
1
解析:
方法1:公式计算:~-2=-(-2+1)=-(-1)=1
方法2:
负数计算时候,要先求补码,即第一步求-2的补码
2= ....0000 0010
取反= ....1111 1101
+1= .... 1111 1110 即-2补码表示为 ....1111 1110
~(-2),此时需要对-2的补码,按位取反,即:
.... 1111 1110取反得到 .... 0000 0001;即转为10进制表示为1
总结:处理负数时,对于负数,要先对于数字进行取反+1,转为补码,再对补码进行运算
补充知识-原码、反码、补码
原码
#原码=符号位+数值位
#+5=0 0101 (0表示正数)
#-5=1 0101 (1表示负数)
此处如果计算5+(-5),按照原码计算为 :0 0101 + 1 0101 = 1 1010 = -10
答案不为0
反码
#反码=符号位不变,数值位全部取反
# +5=0 0101 (0表示正数)
# -5=1 1010 (1表示负数,0101=5,取反=1010)
此处如果计算5+(-5),按照反码计算为 :0 0101 + 1 1010 = 1 1111 = -0
反码中,1 1111,表示负0;即+0(0000 )和-0(1111)还是不一样
补码
#注:负数用补码,补码=反码+1
# +5=0 0101 (0表示正数)
# -5的反码 = 1 1010 (1表示负数,0101=5,取反=1010)
# -5的补码 = 1 1010 +1 = 1 1011
所以 5+(-5)计算为:
# +5=0 0101 (0表示正数)
# -5=1 1011 (1表示负数)
运算结果由低位开始,即逢2进1,则1 0 0000;此处的左起第二位为原来的正负号位,得到的1为溢出位;溢出位直接扔掉;此时最终结果为 0 0000;即为0
1.13 小于 [<] “判断”
判断X是否小于Y,运算结果返回True 或者False
a=3
b=5
c=3
d=3.1415926
print(a<b)
print(d<c)
输出:
True
False
1.14 大于 [>] “判断”
判断X是否大于Y,运算结果返回True 或者False
a=66
b=168
c=3.33333333333
d=3.1415926
print(a>b)
print(c>d)
输出:
False
True
1.15 小于等于 [<=] “判断”
判断X是否小于等于Y,运算结果返回True 或者False
a=168
b=168
c=3.33333333333
d=3.1415926
print(a<=b)
print(c<=d)
输出:
True
False
1.16 大于等于 [>=] “判断”
判断X是否大于等于Y,运算结果返回True 或者False
a=168
b=168
c=3.33333333333
d=3.1415926
print(a>=b)
print(c>=d)
输出:
True
True
1.17 等于 [= =] “判断”
判断X是否等于Y,运算结果返回True 或者False
a=168
b=168
c=3.33333333333
d=3.1415926
print(a==b)
print(c==d)
输出:
True
False
1.18 不等于 [!=] “判断”
判断X是否不等于Y,运算结果返回True 或者False
a=168
b=168
c=3.33333333333
d=3.1415926
print(a!=b)
print(c!=d)
输出:
False
True
1.19 布尔“非” [not] “判断” 真变假,假变真
在空值检查和条件分支,如下:
name = "" #此时name为空
if not name: # 如果 name 是空字符串 ""
print("A")
else:
print(f"B")
输出:
A
或者:
balance = 0
if not balance: # 余额为 0
print("ABCD") #ABCD可以是任何提示
输出:
ABCD
或者:
is_closed = False
if not is_closed:
print("营业中") # 没关门,就是营业中
输出:
营业中
1.20 布尔“与” [and] “判断” 两个都真才算真
多重条件判断,如下:
age = 25
has_id = True
if age >= 18 and has_id:
print("可以进入")
输出:
可以进入
1.21 布尔“或” [or] “判断” 多个条件,只要一个真就真
设置默认值,如下:
name = input("请输入名字:") or "匿名用户"
print(name) # 用户直接回车(空字符串)时,自动用"匿名用户"
输出:
请输入名字:张三 #写了张三,则输出张三
张三
请输入名字: #啥也没写,直接敲回车,默认匿名
匿名用户
浙公网安备 33010602011771号