当前位置: 首页 > 面试题库 >

“and”和“or”如何处理非布尔值?

钱欣悦
2023-03-14
问题内容

我正在尝试学习python,并遇到了一些不错的代码,虽然简短但并不完全有意义

上下文是:

def fn(*args):
    return len(args) and max(args)-min(args)

我知道它在做什么,但是python为什么要这样做-即返回值而不是True / False?

10 and 7-2

返回5。类似,将和更改为或将导致功能更改。所以

10 or 7 - 2

将返回10。

这是合法/可靠的样式,还是对此有任何误解?


问题答案:

TL; DR

我们首先总结两个逻辑运算符and和的两个行为or。这些习语将构成我们下面讨论的基础。

and

如果有,则返回第一个Falsy值,否则返回表达式中的最后一个值。

or

如果有,则返回第一个Truthy值,否则返回表达式中的最后一个值。

行为也总结在docs中,尤其是在此表中:

无论其操作数如何,返回布尔值的唯一运算符是该not运算符。

“真实性”和“真实”评估

该声明

len(args) and max(args) - min(args)

是一种非常 Python式的简洁(并且可能不太可读)的说法,即“如果args不为空,则返回结果max(args) - min(args)”,否则返回0。通常,它是if-else表达式的更简洁表示。例如,

exp1 and exp2

应该(大致)翻译为:

r1 = exp1
if r1:
    r1 = exp2

或者,等效地,

r1 = exp1 if exp1 else exp2

同样,

exp1 or exp2

相当于

r1 = exp1
if not r1:
    r1 = exp2

其中exp1和exp2是任意的python对象,或返回某些对象的表达式。在这里理解逻辑and和or运算符用法的关键是要理解它们不限于对布尔值进行操作或返回布尔值。任何具有真实性值的对象都可以在此处进行测试。这包括int,str,list,dict,tuple,set,NoneType,和用户定义的对象。短路规则也同样适用。

但是什么是真实性?

它指的是在条件表达式中使用对象时如何评估对象。@Patrick Haugh在这篇文章中很好地总结了真实性。

除以下值“ falsy”外,所有值均被视为“真实”值:

  • None
  • False
  • 0
  • 0.0
  • 0j
  • Decimal(0)
  • Fraction(0, 1)
  • [] -一个空的 list
  • {} -一个空的 dict
  • () -一个空的 tuple
  • ’‘ -一个空的 str
  • b’‘ -一个空的 bytes
  • set() -一个空的 set
  • 一个空的range,像range(0)
  • 为其对象
  • obj.bool() 退货 False
  • obj.len() 退货 0

“真实的”值将满足由if或while 语句执行的检查。我们使用“真实的”和“虚假的”来区别 bool值True和False。

如何and运作

我们以OP的问题为基础,讨论在这些情况下如何使用这些运算符。

给定一个带有定义的函数

def foo(*args):
    ...

如何返回零个或多个参数列表中的最小值和最大值之间的差?

找到最小值和最大值很容易(使用内置函数!)。这里唯一的障碍是适当地处理参数列表可能为空的极端情况(例如,调用foo())。由于and操作员,我们可以在一行中完成这两项操作:

def foo(*args):
     return len(args) and max(args) - min(args)
foo(1, 2, 3, 4, 5)
# 4

foo()
# 0

由于and使用,如果第二个表达式为,则还必须对其求值True。请注意,如果第一个表达式的值为真,则返回值始终是第二个表达式的结果。如果第一个表达式的计算结果为Falsy,则返回的结果为第一个表达式的结果。

在上面的函数中,如果foo接收到一个或多个参数,len(args)则大于0(一个正数),因此返回的结果为max(args) - min(args)。OTOH,如果没有参数传递,len(args)是0这是Falsy,并0返回。

请注意,编写此函数的另一种方法是:

def foo(*args):
    if not len(args):
        return 0

    return max(args) - min(args)
或者,更简而言之,

def foo(*args):
    return 0 if not args else max(args) - min(args)

当然,如果这些功能都不执行任何类型检查,那么除非你完全信任所提供的输入,否则请不要依赖于这些结构的简单性。

如何or运作

我or用一个人为的例子以类似的方式解释了它的工作。

给定一个带有定义的函数

def foo(*args):
    ...

你将如何完成foo所有数字的归还9000?

我们or这里用来处理拐角处的情况。我们定义foo为:

def foo(*args):
     return [x for x in args if x > 9000] or 'No number over 9000!'

foo(9004, 1, 2, 500)
# [9004]

foo(1, 2, 3, 4)
# 'No number over 9000!'

foo对列表执行过滤,以保留上的所有数字9000。如果存在任何这样的数字,则列表理解的结果是非空列表,该列表为Truthy,因此将其返回(此处发生短路)。如果不存在这样的数字,则list comp的结果[]为Falsy。因此,现在对第二个表达式求值(一个非空字符串)并返回。

使用条件,我们可以将该函数重写为:

def foo(*args):
    r = [x for x in args if x > 9000]
    if not r:
        return 'No number over 9000!' 

    return r


 类似资料:
  • 问题内容: 是否可以通用地参数化接受EITHER ClassA或InterfaceB的方法? 由于|无法编译 伪码 即我不想编写多个方法签名,而是希望此方法接受Number或CharSequence作为参数 应该通过数字或CharSequence参数传递 问题答案: 如果您 确实 想这样做,则需要将您接受的类包装在自己的自定义类中。在您的示例情况下,可能类似于: 您的方法变为: 然后,您可以构建其

  • 问题内容: 我遇到了很大的麻烦,因为我需要对某些输入类型进行样式化。我有类似的东西: 但是我也不想设置复选框的样式。 我试过了: 如何使用?而且我需要尽快使用,我认为用法将是相同的。 更新: 我仍然不知道如何使用和正确。我在W3文档中找不到任何内容。 问题答案: 通过像这样将多个选择器串在一起来工作: 另一个例子: 通过使用逗号分隔多个选择器来工作,例如:

  • 主要内容:AND 运算符,OR 运算符SQL 中的 AND 和 OR 运算符用来连接多个查询条件,以缩小返回的结果集,它们被称为连接符。 AND 运算符 AND 运算符用于连接 WHERE 子句中的多个查询条件,只有当这些查询条件都被满足时,数据行(记录)才会被选取。 语法 WHERE 子句中 AND 运算符的基本语法如下: SELECT column1, column2, columnN FROM table_name WHERE

  • 问题内容: 我有以下简单的代码行: 这应该很简单,如果我不为空或它不是一个空格,而是打印Something。现在,如果这两个条件之一是,为什么我看到打印了什么? 问题答案: 德摩根定律, 就您而言,根据第一条陈述,您已经有效地撰写了 这是不可能发生的。因此,无论输入是什么,都将始终返回,而取反则将始终给出。 相反,您应该这样写 或根据De Morgan引用的第二条陈述,

  • 问题内容: 我有一个带有三个字段(userId,标题,描述)的索引对象。我想找到标题或说明包含给定关键字的特定用户的所有对象。 我有这样的事情(但这显然是错误的): 如何修改代码以获取具有正确ID和标题或描述中的搜索短语的所有对象? 问题答案: 我认为将是这样的:

  • 问题内容: 请考虑这个例子 位运算符和运算符如何处理布尔变量? 问题答案: Java 中没有按位操作。 并且不在Java中执行按位运算,而是在逻辑运算中进行操作(如 JLS的 §15.22.2中所指定) 。 是逻辑AND(如果且仅当两个参数都为时,它将求和) 是逻辑“或”(如果且仅当至少一个参数为时,它将求和)。 请注意, 同一 运营商用于位运算,但这些只有在两个操作数都是一个类型,可转换为一个整