Python False obj.\uuu len\uuu()返回0

Python False obj.\uuu len\uuu()返回0,python,operators,logical-operators,Python,Operators,Logical Operators,“truthy”值将满足if或while 声明。我们用“真”和“假”来区别 bool值True和False 和的工作原理 我们以OP的问题为基础,继续讨论这些操作符在这些情况下是如何工作的 给定一个定义为 def foo(*args): ... def foo(*args): ... 如何返回最小值和最大值之间的差值 在零个或多个参数的列表中 找到最小值和最大值很容易(使用内置函数!)。这里唯一的障碍是正确处理参数列表可能为空的情况(例如,调用foo())。由于和运算符,我

“truthy”值将满足
if
while
声明。我们用“真”和“假”来区别
bool
True
False


的工作原理 我们以OP的问题为基础,继续讨论这些操作符在这些情况下是如何工作的

给定一个定义为

def foo(*args):
    ...
def foo(*args):
    ...
如何返回最小值和最大值之间的差值 在零个或多个参数的列表中

找到最小值和最大值很容易(使用内置函数!)。这里唯一的障碍是正确处理参数列表可能为空的情况(例如,调用
foo()
)。由于
运算符,我们可以在一行中同时执行这两项操作:

def foo(*args):
     return len(args) and max(args) - min(args)
由于使用了
,如果第一个表达式为
,则还必须计算第二个表达式。请注意,如果第一个表达式的计算结果为truthy,则返回值始终是第二个表达式的结果。如果第一个表达式的计算结果为Falsy,则返回的结果是第一个表达式的结果

在上面的函数中,如果
foo
接收到一个或多个参数,
len(args)
大于
0
(一个正数),则返回的结果是
max(args)-min(args)
。OTOH,如果没有传递任何参数,
len(args)
0
,这是错误的,并且返回
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)
当然,如果这些函数都不执行任何类型检查,那么除非您完全信任提供的输入,否则不要依赖这些构造的简单性


的工作原理 我用一个人为的例子以类似的方式解释了
的工作原理

给定一个定义为

def foo(*args):
    ...
def foo(*args):
    ...
您如何填写
foo
以返回超过
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
上的所有数字。如果存在任何这样的数字,列表理解的结果是一个非空的列表,它是真实的,因此它被返回(在这里短路)。如果不存在这样的数字,则列表comp的结果是
[]
,这是错误的。因此,现在对第二个表达式求值(非空字符串)并返回

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

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

与以前一样,此结构在错误处理方面更加灵活。

执行布尔逻辑,但它们在比较时返回一个实际值。使用时,将在布尔上下文中从左到右计算值0、、[]、()、{}、None在布尔上下文中为false;其他一切都是真的

如果布尔上下文中的所有值均为true,返回最后一个值

>>> 2 and 5
5
>>> 2 and 5 and 10
10
如果布尔上下文中有任何值为false,则返回第一个false值

>>> '' and 5
''
>>> 2 and 0 and 5
0
那么代码呢

return len(args) and max(args)-min(args)
当存在args时,返回
max(args)-min(args)
的值,否则返回
len(args)
,该值为0

这是合法/可靠的风格,还是有什么问题

我想补充一点,它不仅合法可靠,而且非常实用。下面是一个简单的例子:

>>>example_list = []
>>>print example_list or 'empty list'
empty list
因此,你可以真正利用它在你的优势。我是这样看待这一点的:

操作员

Python的
运算符返回第一个Truth-y值或最后一个值,然后停止

操作员

Python的
运算符返回第一个False-y值或最后一个值,并停止

幕后

在python中,除了0之外,所有数字都被解释为
True
。所以说,

0 and 10 
同:

False and True
这显然是
False
。因此,它返回0

Gotchas是合乎逻辑的 是的,有一些陷阱

fn()==fn(3)==fn(4,4)
首先,如果
fn
返回
0
,则无法知道调用它时是否没有任何参数,是使用一个参数还是使用多个相等的参数:

>>> fn()
0
>>> fn(3)
0
>>> fn(3, 3, 3)
0
fn
是什么意思? 然后,Python是一种动态语言。它没有指定
fn
做什么,输入应该是什么,输出应该是什么样子。因此,正确命名函数非常重要。类似地,不必调用参数
args
delta(*numbers)
计算范围(*numbers)
可以更好地描述函数应该做什么

参数错误 最后,逻辑
运算符应该能够防止在没有任何参数的情况下调用函数时失败。但是,如果某个参数不是数字,它仍然会失败:

>>> fn('1')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in fn
TypeError: unsupported operand type(s) for -: 'str' and 'str'
>>> fn(1, '2')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in fn
TypeError: '>' not supported between instances of 'str' and 'int'
>>> fn('a', 'b')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in fn
TypeError: unsupported operand type(s) for -: 'str' and 'str'
例如:

>>> delta()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 7, in delta
ValueError: delta should be called with at least one numerical argument
>>> delta(3)
0
>>> delta('a')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in delta
ValueError: delta should only be called with numerical arguments
>>> delta('a', 'b')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in delta
ValueError: delta should only be called with numerical arguments
>>> delta('a', 3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in delta
ValueError: delta should only be called with numerical arguments
>>> delta(3, 4.5)
1.5
>>> delta(3, 5, 7, 2)
5

简单地理解,

和:
如果第一个值为假,则返回第一个值,否则返回第二个值

例如:

但是,

和=>如果有人错了,那就是错的。如果两者都是真的,那么只有它会成为真的

或:
如果第一个值为假,则返回第二个值,否则返回第一个值

原因是,若第一个为假,则检查2是否为真

例如:

但是,

或=>如果有人错了,那就是真的。所以,若第一个值为false,不管2的值是什么。 所以它返回第二个值,不管它是什么

如果
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)
def foo(*args):
    ...
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!'
def foo(*args):
    r = [x for x in args if x > 9000]
    if not r:
        return 'No number over 9000!' 
    
    return r
>>> 2 and 5
5
>>> 2 and 5 and 10
10
>>> '' and 5
''
>>> 2 and 0 and 5
0
return len(args) and max(args)-min(args)
>>>example_list = []
>>>print example_list or 'empty list'
empty list
0 and 10 
False and True
>>> fn()
0
>>> fn(3)
0
>>> fn(3, 3, 3)
0
>>> fn('1')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in fn
TypeError: unsupported operand type(s) for -: 'str' and 'str'
>>> fn(1, '2')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in fn
TypeError: '>' not supported between instances of 'str' and 'int'
>>> fn('a', 'b')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in fn
TypeError: unsupported operand type(s) for -: 'str' and 'str'
def delta(*numbers):
    try:
        return max(numbers) - min(numbers)
    except TypeError:
        raise ValueError("delta should only be called with numerical arguments") from None
    except ValueError:
        raise ValueError("delta should be called with at least one numerical argument") from None
>>> delta()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 7, in delta
ValueError: delta should be called with at least one numerical argument
>>> delta(3)
0
>>> delta('a')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in delta
ValueError: delta should only be called with numerical arguments
>>> delta('a', 'b')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in delta
ValueError: delta should only be called with numerical arguments
>>> delta('a', 3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in delta
ValueError: delta should only be called with numerical arguments
>>> delta(3, 4.5)
1.5
>>> delta(3, 5, 7, 2)
5
>>> def delta(*numbers):
...     try:
...         return max(numbers) - min(numbers)
...     except TypeError:
...         raise ValueError("delta should only be called with numerical arguments") from None
...     except ValueError:
...         return -1 # or None
... 
>>> 
>>> delta()
-1
1 and 2 # here it will return 2 because 1 is not False
0 and 2 # will return 0 because first value is 0 i.e False
1 or 2 # here it will return 1 because 1 is not False
0 or 2 # will return 2 because first value is 0 i.e False