卡码笔记-最强八股文
首页
计算机基础
Python
C++
Java
Go
🔥大模型🔥
  • 大模型面经
  • Java面经
  • C++面经
大模型Github (opens new window)
代码随想录 (opens new window)
首页
计算机基础
Python
C++
Java
Go
🔥大模型🔥
  • 大模型面经
  • Java面经
  • C++面经
大模型Github (opens new window)
代码随想录 (opens new window)
  • 本栏必读

    • Python面试题专栏介绍
    • Python学习路线
    • Python零基础入门课
  • 基础语法

    • Python有哪些内置数据类型?
    • Python变量保存的是什么?
    • 可变对象和不可变对象有什么区别?
    • is和==有什么区别?
    • Python的运算符有哪些?
      • 简要回答
      • 详细回答
      • 知识拓展
    • Python条件判断和循环的常见写法与易错点
    • Python字符串为什么不可变?
    • Python列表和元组有什么区别?
    • Python字典和集合有什么区别?
    • Python切片和序列解包怎么用?
    • 列表、字典和集合推导式怎么写?
  • 函数、作用域与模块

  • 面向对象

  • 进阶语法与语言机制

# Python的运算符有哪些?and、or为什么会返回对象?

面试官问:"Python有哪些运算符?and和or为什么不总是返回True或False?"

很多人会列举加减乘除、大于小于,但对逻辑运算符的返回值感到困惑。看到3 and 5返回5、0 or "hello"返回"hello",以为是特殊情况。真正要讲清楚的是:Python的and、or采用短路求值,返回的是决定真假的那个对象本身,而不是转换后的布尔值。

# 简要回答

Python运算符按功能分为:算术运算符(+、-、*、/、//、%、**)、比较运算符(==、!=、>、<、>=、<=、is、is not、in、not in)、逻辑运算符(and、or、not)、位运算符(&、|、^、~、<<、>>)、赋值运算符(=、+=、-=等)和其他运算符(如海象运算符:=)。

and和or采用短路求值,返回决定结果的对象,而不是True或False。x and y在x为假时返回x,否则返回y;x or y在x为真时返回x,否则返回y。这种设计让表达式更简洁,比如result = x or default可以在x为空时使用默认值。

not是唯一总是返回布尔值的逻辑运算符,它对操作数取反后返回True或False。

# 详细回答

# 算术运算符

常见的数学运算:

print(10 / 2)    # 5.0,真除法总是返回浮点数
print(-7 // 2)   # -4,地板除向负无穷取整
print(-7 % 2)    # 1,余数符号跟随除数
print(2 ** 10)   # 1024
1
2
3
4

/总是返回浮点数,即使能整除。//是向下取整,对负数来说是朝负无穷方向,所以-7 // 2是-4而不是-3。%和//配套,满足a == (a // b) * b + a % b,因此余数的符号跟随除数。这两点是C/Java转过来的录友最容易踩的坑。

# 比较运算符

==、<这类比较对内置类型返回True或False。Python的比较运算符支持链式比较,1 < x < 10等价于1 < x and x < 10,中间的x只计算一次:

age = 25
print(18 <= age < 60)  # True
print(1 < 3 > 2)       # True,等价于 1 < 3 and 3 > 2
1
2
3

is和is not比较对象身份,已在《is和==有什么区别?》中详细讲解。

in和not in判断成员关系,比如3 in [1, 2, 3]、"py" in "python"。它的本质是调用容器的__contains__()方法,没有该方法时退回到迭代逐个比较。

# 逻辑运算符:and、or、not

这是面试重点。先明确真值测试:在if、while、and、or、not这类需要判断真假的位置,Python会检查对象的真假。None、False、数值零(0、0.0)、空容器(""、[]、{}、set()等)为假,其余对象默认为真。自定义类可以通过__bool__()或__len__()改变规则。

and和or只用真值测试做判断,返回的却是原来的操作数对象,不是布尔值。

and:遇假即停

x and y的求值规则:

  1. 先计算x,如果x为假,直接返回x,不再计算y。
  2. 如果x为真,返回y(不管y真假)。

or:遇真即停

x or y的求值规则:

  1. 先计算x,如果x为真,直接返回x,不再计算y。
  2. 如果x为假,返回y(不管y真假)。

用一段代码同时验证两条规则:

print(0 and 5)          # 0,左边为假,直接返回左边
print(3 and 5)          # 5,左边为真,返回右边
print([] or "default")  # default,左边为假,返回右边
print("Carl" or "anon") # Carl,左边为真,直接返回左边

nickname = ""
print(nickname or "匿名用户")  # 匿名用户
1
2
3
4
5
6
7

nickname or "匿名用户"是常见的默认值写法:空字符串为假,or返回右边的对象。它的坑在于0、""、[]都会被当成"没有值"。如果0是合法输入,就要写成x if x is not None else default。

not总是返回布尔值

not 0是True,not [1, 2]是False。它只有一个操作数,不存在短路问题,也不会返回原对象。

and与or的短路求值流程

图中展示了and和or的短路求值机制:and在左侧为假时直接返回左侧对象,or在左侧为真时直接返回左侧对象,都不会继续计算右侧表达式。

# 短路求值的实际意义

短路求值不仅是性能优化,还能避免错误:

data = []
if data and data[0] == 1:
    print("第一个元素是1")
print("没有报错")  # 没有报错
1
2
3
4

data是空列表,and在左边就停下了,data[0]根本不会执行,所以不会抛IndexError。同理,user and user.name可以在user为None时避免AttributeError。把"保护条件"写在and左边,是短路求值最常见的用法。

# 位运算符

对整数的二进制位进行操作:

运算符 含义 示例
& 按位与 5 & 3 → 1
\| 按位或 5 \| 3 → 7
^ 按位异或 5 ^ 3 → 6
~ 按位取反 ~5 → -6
<< 左移 5 << 1 → 10
>> 右移 5 >> 1 → 2

&、|不是逻辑运算符。它们不短路,两边都会求值;对bool使用时虽然能得到True或False,但和比较运算混用时优先级会坑人:x > 1 & x < 5实际是x > (1 & x) < 5。条件判断一律用and、or。

# 赋值运算符

=把名字绑定到对象,+=、-=、*=等是复合赋值。x += 1看起来等价于x = x + 1,但对可变对象并不完全一样:列表的+=会调用__iadd__()原地修改,x = x + [1]则创建新列表再重新绑定。如果还有其他名字指向原列表,两种写法的结果就不一样。这一点和《可变对象与不可变对象》直接相关。

Python 3.8引入了海象运算符:=(赋值表达式),可以在表达式中同时赋值和使用值:

words = ["python", "go", "javascript"]
if (n := len(words)) > 2:
    print(f"共{n}个单词")  # 共3个单词
1
2
3

海象运算符可以减少重复计算或重复调用,但不要滥用,影响可读性时还是拆开写更清楚。

# 运算符优先级

常见优先级从高到低:

  1. **(幂运算)
  2. ~、+、-(一元运算符)
  3. *、/、//、%
  4. +、-(二元加减)
  5. <<、>>(位移)
  6. &(按位与)
  7. ^(按位异或)
  8. |(按位或)
  9. 比较运算符(==、!=、>、<等)
  10. not
  11. and
  12. or

两个容易错的点:**右结合且高于一元负号,所以-2 ** 2是-4;not低于比较运算,所以not x == y是not (x == y)。拿不准就加括号。

# 知识拓展

面试官可能追问:

Q1:老代码里的cond and a or b有什么问题?

这是三元表达式出现前的模拟写法,问题在于a为假时会错误地返回b。比如True and 0 or 10结果是10而不是0。Python 2.5起就有条件表达式,直接写a if cond else b。

Q2:1 or 2 and 0返回什么?

返回1。and优先级高于or,表达式等价于1 or (2 and 0);左边1为真,or直接短路,右边根本不计算。

Q3:in运算符的时间复杂度是多少?

取决于容器。列表、元组、字符串需要逐个比较,是O(n);集合和字典的键基于哈希查找,平均是O(1)。频繁做成员判断时,先把数据转成集合。

Q4:为什么~5等于-6?

Python的整数语义规定~x等于-(x+1),可以理解为在无限位补码下按位取反。Python整数没有固定位宽,所以不会像C语言那样出现~5等于某个大正数的情况。

Q5:a < b < c和a < b and b < c完全等价吗?

结果一样,但链式比较中的b只计算一次。如果b是一个有副作用或很耗时的函数调用,两种写法的行为就会不同。

Last Updated: 10/13/2026, 5:57:00 PM

← is和==有什么区别? Python条件判断和循环的常见写法与易错点 →

评论

验证登录状态...

侧边栏 侧边栏
夜间模式 夜间
卡码简历 卡码简历
代码随想录 代码随想录
卡码投递表 卡码投递表🔥
2026实习校招群 2026群
添加客服微信 2026实习校招客服微信 PS:通过微信后,请发送姓名-学校-年级-2026实习/校招
支持卡码笔记 支持卡码笔记
鼓励/支持/赞赏Carl 卡码笔记赞赏码
1. 如果感觉本站对你很有帮助,也可以请Carl喝杯奶茶,金额大小不重要,心意已经收下
2. 希望大家都能梦想成真,有好的前程,加油💪