我不明白这种语法。
Python程序演示三元运算符
a, b = 10, 20
使用元组选择项目
print( (b, a) [a < b] )
使用词典选择项目
print({True: a, False: b} [a < b])
PS:我想这是来自旧版本的Python,因为在较新版本中(不知道从哪个版本)True和False是保留关键字,因此无法为它们分配值。
lamda比上面两种方法更有效,因为在lambda中我们确保只有一个表达式将被计算,不像元组和字典
print((lambda: b, lambda: a)[a < b]())
语法应该是:
[on_true] if [expression] else [on_false]
那怎么办?
print( (b, a) [a < b] )
print({True: a, False: b} [a < b])
print((lambda: b, lambda: a)[a < b]())
适合这种语法?在tuple / dictionary / lambda之后[a<b]
的含义是什么?我以前从未见过这种语法。列表[b, a]
在[a<b]
之前也有效。
我希望它看起来像这样
print( a if a < b else b )
链接到资源:https://www.geeksforgeeks.org/ternary-operator-in-python/
首先请注意,所有这些都给出了a
和b
的最小值:
a, b = 10, 20
res1 = (b, a)[a < b] # 10
res2 = {True: a, False: b}[a < b] # 10
res3 = (lambda: b, lambda: a)[a < b]() # 10
我们可以依次考虑这些:
res1
构造了2个整数的tuple
。 a < b
返回一个布尔值,在本例中为True
。在Python中,True == 1
,因为bool
是int
的子类。最后,[]
是__getitem__
的语法糖,这是一种称为位置索引的方法。由于Python从0
开始计数,第一个索引是a
。你也可以自己确认:(b, a).__getitem__(1)
返回10
。res2
构造一个字典,将布尔值映射到a
和b
。在__getitem__
对象上调用dict
会返回给定键的值。像以前一样,关键是True
。由于字典将True
映射到a
,因此这是返回的值。res3
构造了一个匿名(lambda
)函数的元组,每个函数返回标量,即b
和a
。根据res1
,可以通过整数索引从元组中提取项目。唯一的额外要求是通过lambda
实际调用()
函数。请注意,这些操作都不会与应用的ternary operator相同
在编译时
(见注释)通过内联if
/ else
:
res4 = a if a < b else b
a<b
是bool
(True
或False
)。由于bool
是int
的子类型,因此它可以用于预期整数的上下文中,例如,作为列表/元组索引:
>>> True == 1
True
>>> False == 0
True
>>> isinstance(True, int)
True
>>> ('a', 'b')[True] # True == 1
'b'
>>> ('a', 'b')[1<2] # 1<2 == True == 1
'b'
>>> ('a', 'b')[2<1] # 2<1 == False == 0
'a'
对于dict
键,它是类似的,但甚至不需要类型强制:
>>> {True: 'a', False: 'b'}[1<2] # 1<2 == True
'a'
你的误解可能是关于<b。
在所有这些情况下,评估a <b的布尔结果用作之前对象的键。
如果是
print( (b, a) [a < b] )
和
print((lambda: b, lambda: a)[a < b]())
该对象是一个元组,包含变量本身或非常简单的匿名函数,它们返回这些变量。
如果是
print({True: a, False: b} [a < b])
表达式被计算并用作字典的键,它具有True和False作为键。假设这意味着它必须是较旧的Python版本是错误的,因为字典不代表值的重新分配,而仅仅是数据结构,其中键映射到值。 True和False是有效的密钥,这种情况正是在这里使用的。
最后:
print( a if a < b else b )
是一个很好的,简洁的表达同样的事情,事实上我会在这种情况下使用的代码行