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)   # 用户直接回车(空字符串)时,自动用"匿名用户"

输出:

请输入名字:张三  #写了张三,则输出张三
张三   

请输入名字:  #啥也没写,直接敲回车,默认匿名
匿名用户

posted @ 2026-08-06 15:12  两块饼干  阅读(2)  评论(0)    收藏  举报