Python 3.8 中的海象运算符,优雅而简洁

2023-06-0908:51:50编程语言入门到精通Comments1,452 views字数 3749阅读模式

概念介绍

:= 可在表达式内部为变量赋值。它被昵称为“海象运算符”因为它很像是 [海象的眼睛和长牙]。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/46221.html

Python 3.8 中的海象运算符,优雅而简洁

实用价值

「一方面,可以写出优雅而简洁的 Python 代码;另一方面,可以看懂他人的代码。」文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/46221.html

演示示例

官网的例子

「看下官网给出的例子:」文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/46221.html

Python 3.8 中的海象运算符,优雅而简洁

通过使用海象表达式,避免len()方法运行两次,从而提高了运行速度。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/46221.html

# 通过使用海象表达式,避免len()方法运行两次,从而提高了运行速度
a = [1, 2, 3, 4, 5, 6, 7, 8, 9]

if len(a) > 10:
    print(f"List is to long({len(a)} elements, expected <= 10)")

# 改进版
n = len(a)
if n > 10:
    print(f"List is to long({n} elements, expected <= 10)")


# 直接使用 海象运算符
if (n := len(a)) > 10:
    print(f"List is too long ({n} elements, expected <= 10)")

「类似的例子还有:」文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/46221.html

用于是否匹配,提取子分组。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/46221.html

discount = 0.0
if (mo := re.search(r'(\d+)% discount', advertisement)):
    discount = float(mo.group(1)) / 100.0
# 以前的写法是这样:
discount = 0.0
mo = re.search(r'(\d+)% discount', advertisement)
if mo:
    discount = float(mo.group(1)) / 100.0

运算符也适用于配合 while 循环计算一个值来检测循环是否终止,而同一个值又在循环体中再次被使用的情况:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/46221.html

# Loop over fixed length blocks
while (block := f.read(256)) != '':
    process(block)
# 老的写法
while 1:
    block = f.read(256)
    if block != '':
        process(block)
 else:        
  break

另一个值得介绍的用例出现于列表推导式中,在筛选条件中计算一个值,而同一个值又在表达式中需要被使用:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/46221.html

[clean_name.title() for name in names if (clean_name := normalize('NFC', name)) in allowed_names]

文档中也提到了:「请尽量将海象运算符的使用限制在清晰的场合中,以降低复杂性并提升可读性。」文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/46221.html

练习的例子

# 2023/5/14 12:30 , @File: test_1.py, @Comment : python3.9.7
# Python 海象运算符 简单介绍

x = 5
if x <= 10:
    print("Please enter a number greater than or equal to 10")
print("================================================")
# 海象运算符
if (y := 5) < 10:
    print("Please enter a number greater than or equal to 10")

# 2023/5/14 12:35 , @File: test_2.py, @Comment : python3.9.7
num = 10
while num:
    print("the number of iterations is " + str(num))
    num -= 1
# 海象运算符

print("================================================")
count = 10
while count := count - 1:
    print("the number of iterations is " + str(count))
# 2023/5/14 12:39 , @File: test_3.py, @Comment : python3.9.7
nums = [1, 2, 3, 4, 5, 6, 7, 8, 9]


def f(x):
    return x ** 2


nums2 = [n for i in nums if (n:=f(i))>10 ]
# 2023/5/14 15:19 , @File: test_6.py, @Comment : python3.9.7
nums = [16, 36, 49, 64]


def f(x):
    print('运行了函数f(x)1次。')
    return x ** 0.5


print([f(i) for i in nums if f(i) > 5])

print("================================================")
nums2 = [16, 36, 49, 64]


def f2(x):
    print('运行了函数f2(x)1次。')
    return x ** 0.5


print([n for i in nums if (n := f2(i)) > 5])
# 
# 运行了函数f(x)1次。
# 运行了函数f(x)1次。
# 运行了函数f(x)1次。
# 运行了函数f(x)1次。
# 运行了函数f(x)1次。
# 运行了函数f(x)1次。
# 运行了函数f(x)1次。
# [6.0, 7.0, 8.0]
# ================================================
# 运行了函数f2(x)1次。
# 运行了函数f2(x)1次。
# 运行了函数f2(x)1次。
# 运行了函数f2(x)1次。
# [6.0, 7.0, 8.0]

注意事项

  • 赋值表达式使用walrus运算符(:=)在单个表达式中同时对变量名进行赋值和计算,从而减少重复。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/46221.html
      上面的 if,while,列表推导的例子上都有体现。
    
  • 当赋值表达式是一个较大表达式的子表达式时,它必须用圆括号括起来文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/46221.html
    # 2023/5/14 12:59 , @File: test_4.py, @Comment : python3.9.7
    countries = ["India", "USA", "France"]
    if len(countries) < 5:
        print("Length of countries is %d" % len(countries))
    
    # 上面的代码执行会调用len两次,我们改进下:
    
    countries2 = ["India", "USA", "France", "United States", "china", "america"]
    
    countries_size2 = len(countries2)
    if countries_size2 < 10:
        print("Length of countries is  %d" % countries_size2)
    
    # 海象运算符写法
    
    countries3 = ["India", "USA", "France"]
    
    if countries_size3 := len(countries3) < 5:
        print(countries_size3) # True
        print("Length of countries is  %d" % countries_size3)
    
    #  注意下面和上面的写法的区别,用海象得加括号。不然,它会先算后面的比较运算符,然后再海象。
    countries3 = ["India", "USA", "France"]
    
    if (countries_size4 := len(countries3)) < 5:
        print("Length of countries is  %d" % countries_size4)
    
    # Length of countries is 3
    # Length of countries is  6
    # True
    # Length of countries is  1
    # Length of countries is  3
    
    
  • 这里有几个地方不允许使用赋值表达式,以避免歧义或用户混淆文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/46221.html

Python 3.8 中的海象运算符,优雅而简洁「更多信息可以参考:」文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/46221.html

https://peps.python.org/pep-0572/#exceptional-cases文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/46221.html

参考资料

序号文章链接备注
1https://peps.python.org/pep-0572/#rationale官方文档
2https://blog.csdn.net/qq_40244755/article/details/102685199官网例子的解读
3https://zhuanlan.zhihu.com/p/351140647
文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/46221.html
  • 本站内容整理自互联网,仅提供信息存储空间服务,以方便学习之用。如对文章、图片、字体等版权有疑问,请在下方留言,管理员看到后,将第一时间进行处理。
  • 转载请务必保留本文链接:https://www.cainiaoxueyuan.com/ymba/46221.html

Comment

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定