编程语言
首页 > 编程语言> > python – 奇怪地使用“和”/“或”运算符

python – 奇怪地使用“和”/“或”运算符

作者:互联网

我正在尝试学习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

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

and

Return the first Falsy value if there are any, else return the last
value in the expression.

or

Return the first Truthy value if there are any, else return the last
value in the expression.

该行为也在the docs中进行了总结,尤其是在此表中:

enter image description here

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

“真实”和“Truthy”评估

该声明

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

是一个非常pythonic简洁(可以说是不太可读)的方式说“如果args不为空,返回max(args) – min(args)”的结果,否则返回0.一般来说,它是一个更简洁的表示形式一个if-else表达式.例如,

exp1 and exp2

应该(粗略地)翻译成:

r1 = exp1
if not r1:
    r1 = exp2

或者,等效地,

r1 = exp1 if exp1 else exp2

其中exp1和exp2是任意python对象,或返回某个对象的表达式.理解逻辑和和或运算符的使用的关键是理解它们不限于操作或返回布尔值.任何具有真值的对象都可以在这里进行测试.这包括int,str,list,dict,tuple,set,NoneType和用户定义的对象.短路规则仍然适用.

但是什么是真实性?
它指的是在条件表达式中使用对象的方式. @Patrick Haugh在this post很好地总结了真实性.

All values are considered “truthy” except for the following, which are
“falsy”:

  • None
  • False
  • 0
  • 0.0
  • 0j
  • Decimal(0)
  • Fraction(0, 1)
  • [] – an empty list
  • {} – an empty dict
  • () – an empty tuple
  • '' – an empty str
  • b'' – an empty bytes
  • set() – an empty set
  • an empty range, like range(0)
  • objects for which
    • obj.__bool__() returns False
    • obj.__len__() returns 0

A “truthy” value will satisfy the check performed by if or while
statements. We use “truthy” and “falsy” to differentiate from the
bool values True and False.

如何和工作

我们以OP的问题为基础,讨论这些运算符在这些情况下的运作方式.

Given a function with the definition

06004

How do I return the difference between the minimum and maximum value
in a list of zero or more arguments?

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

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

foo()
# 0

从而使用,如果第一个表达式为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)

如果当然,这些函数都不执行任何类型检查,因此除非您完全信任所提供的输入,否则不要依赖这些结构的简单性.

如何或工作

我用一个人为的例子来解释工作或类似的方式.

Given a function with the definition

06004

How would you complete foo to return all numbers over 9000?

我们在这里使用或处理角落案例.我们将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,因此它被返回(在此处短路).如果不存在这样的数字,则列表comp的结果是[],这是Falsy.因此,现在评估第二个表达式(非空字符串)并返回.

使用条件,我们可以重写这个函数,

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

    return r

和以前一样,这种结构在错误处理方面更加灵活.

标签:python,operators,logical-operators
来源: https://codeday.me/bug/20190911/1803468.html