社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

与python列表一起使用的and运算符[重复]

NS0 • 4 年前 • 621 次点击  

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

这是合法/可靠的款式,还是有什么问题?

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/43435
 
621 次点击  
文章 [ 7 ]  |  最新文章 4 年前
emmanuelsa
Reply   •   1 楼
emmanuelsa    6 年前

对。这是正确的行为和比较。

至少在python中, A and B 收益率 B 如果 A 本质上 True 包括如果 不为空,不为 None 不是空的容器(例如 list , dict 等)。 返回IFF 本质上 False 没有 或空或空。

另一方面, A or B 收益率 如果 本质上 包括如果 不为空,不为 没有 不是空的容器(例如 列表 , 双关语 ,否则返回 .

很容易不注意(或忽略)这种行为,因为在python中, non-null 非空对象的计算结果为true,将被视为布尔值。

例如,以下所有内容都将打印“true”

if [102]: 
    print "True"
else: 
    print "False"

if "anything that is not empty or None": 
    print "True"
else: 
    print "False"

if {1, 2, 3}: 
    print "True"
else: 
    print "False"

另一方面,以下所有内容都将打印“false”

if []: 
    print "True"
else: 
    print "False"

if "": 
    print "True"
else: 
    print "False"

if set ([]): 
    print "True"
else: 
    print "False"
scharette
Reply   •   2 楼
scharette    6 年前

这是合法/可靠的款式,还是有什么问题?

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

>>>example_list = []
>>>print example_list or 'empty list'
empty list

因此,你可以真正利用它为你的利益。为了行割礼,我是这样看的:

Or 操作人员

蟒蛇 or 运算符返回第一个truth-y值或最后一个值,并停止

And 操作人员

蟒蛇 and 运算符返回第一个false-y值或最后一个值,并停止

幕后

在python中,所有数字都被解释为 True 除了0。因此,说:

0 and 10 

同:

False and True

很明显 False . 因此,它返回0是合乎逻辑的

Eric Duminil
Reply   •   3 楼
Eric Duminil    6 年前

高查斯

是的,有一些问题。

fn() == fn(3) == fn(4, 4)

首先,如果 fn 收益率 0 您不能知道它是否被调用,没有任何参数,只有一个参数或多个相等的参数:

>>> fn()
0
>>> fn(3)
0
>>> fn(3, 3, 3)
0

什么? FN 意思是?

那么,python是一种动态语言。没有具体说明什么 FN 是的,它的输入应该是什么,输出应该是什么样子。因此,正确命名函数非常重要。同样,不必调用参数 args . delta(*numbers) calculate_range(*numbers) 可以更好地描述函数应该做什么。

参数错误

最后,合乎逻辑的 and 运算符应该防止函数在没有任何参数的情况下调用时失败。如果某个参数不是数字,它仍然失败,尽管:

>>> 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'

可能的替代方案

下面是根据 "Easier to ask for forgiveness than permission." principle :

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

如果你真的不想在 delta 在没有任何参数的情况下调用,您可以返回一些其他情况下无法返回的值(例如。 -1 None ):

>>> 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
salparadise
Reply   •   4 楼
salparadise    6 年前

这是合法/可靠的款式,还是有什么问题?

这是合法的,这是 short circuit evaluation 返回最后一个值的位置。

你提供了一个很好的例子。函数将返回 0 如果没有传递参数,并且代码不必检查没有传递参数的特殊情况。

另一种使用方法是将none参数默认为可变原语,如空列表:

def fn(alist=None):
    alist = alist or []
    ....

如果一些不真实的价值被传递给 alist 它默认为空列表,避免 if 声明和 mutable default argument pitfall

Nithin Varghese
Reply   •   5 楼
Nithin Varghese    6 年前

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

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

>>> 2 and 5
5
>>> 2 and 5 and 10
10

如果布尔上下文中的任何值为false 返回第一个假值。

>>> '' and 5
''
>>> 2 and 0 and 5
0

所以代码

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

返回的值 max(args)-min(args) 如果有的话 阿尔茨海默病 否则它会回来 len(args) 哪一个是0。

Amit Joki
Reply   •   6 楼
Amit Joki    6 年前

引用 Python Docs

请注意,两者都不是 and 也不 or 限制 这个 价值 类型 他们回来了 到 False True ,而是返回 最后计算的参数 . 这个 有时是有用的,例如,如果 s 应该替换为 默认值如果为空,则表达式 s or 'foo' 收益率 期望值。

这就是Python是如何评估布尔表达式的,上面的文档让我们了解了为什么他们这样做。

要获取布尔值,只需对其进行类型转换。

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

为什么?

短路。

例如:

2 and 3 # Returns 3 because 2 is Truthy so it has to check 3 too
0 and 3 # Returns 0 because 0 is Falsey and there's no need to check 3 at all

同样的道理 也就是说,它将返回 诚实的 一旦找到它,因为计算表达式的其余部分是多余的。

而不是返回核心 ,python返回 诚实的 法西 ,无论如何,这将评估为 . 你可以按原样使用这个表达式,它仍然有效。


知道什么是 诚实的 法西 检查 Patrick Haugh's answer

cs95
Reply   •   7 楼
cs95    5 年前

DR

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

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

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

这些行为也总结在 the docs ,尤其是在这个表中:

enter image description here

返回布尔值的唯一运算符是 not 操作员。


“真实”和“真实”评价

声明

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

是一个 非常 小精灵 简洁(而且不太可读)的表达方式 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 ,以及用户定义的对象。短路规则仍然适用。

但什么是真实?
它指的是在条件表达式中使用对象时如何计算对象。@帕特里克·豪在书中很好地总结了真理。 this post .

所有的价值观都被认为是“真理”,除了以下的 “法西斯”:

  • None
  • False
  • 0.0
  • 0j
  • Decimal(0)
  • Fraction(0, 1)
  • [] 空的 列表
  • {} 空的 双关语
  • () 空的 元组
  • '' 空的 STR
  • b'' 空的 bytes
  • set() 空的 设置
  • 空的 range ,像 range(0)
  • 对象
    • obj.__bool__() 收益率
    • obj.__len__() 收益率

“truthy”值将满足 if while 声明。我们用“truthy”和“falsy”来区别 bool 价值观 True .


怎么 作品

我们以op的问题为基础,讨论了在这些情况下这些运算符是如何实现的。

给出一个函数的定义

def foo(*args):
    ...

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

找到最小值和最大值很容易(使用内置函数!)。这里唯一的障碍是适当地处理参数列表可能为空的角点情况(例如,调用 foo() )我们可以做到这两个在一条线上感谢 操作员:

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

foo(1, 2, 3, 4, 5)
# 4

foo()
# 0

自从 如果第一个表达式是 . 注意,如果第一个表达式的计算结果为truthy,则返回值为 总是 结果是 第二个表达式 . 如果第一个表达式的计算结果为false,则返回的结果是第一个表达式的结果。

在上面的函数中,如果 foo 接收一个或多个参数, len(args) 大于 (正数),因此返回的结果是 最大(args)-最小(args) . 哦,如果没有参数被传递, 伦琴(ARGS) 那是假的,而且 返回。

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

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(*参数):
…

你将如何完成 返回所有数字 9000 ?

我们使用 来处理这个角落的案子。我们定义 AS:

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!'

对列表执行筛选以保留所有数字 九千 . 如果存在任何这样的数字,则列表理解的结果是一个非空列表,这是正确的,因此将返回该列表(此处短路)。如果没有这样的数字,那么列表comp的结果是 [] 这是假的。所以第二个表达式现在被求值(非空字符串)并返回。

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

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

    return r

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