Python黑魔法手册 2.0 文档第三章:炫技魔法操作【5-6】

Python黑魔法手册 2.0 文档

第三章:炫技魔法操作【5-6】

3.5 判断是否包含子串的七种方法

1、使用 in 和 not in
innot in 在 Python 中是很常用的关键字,我们将它们归类为 成员运算符

使用这两个成员运算符,可以很让我们很直观清晰的判断一个对象是否在另一个对象中,示例如下:

>>> "llo" in "hello, python"
True
>>>
>>> "lol" in "hello, python"
False

2、使用 find 方法

使用 字符串 对象的 find 方法,如果有找到子串,就可以返回指定子串在字符串中的出现位置,如果没有找到,就返回 -1

>>> "hello, python".find("llo") != -1
True
>>> "hello, python".find("lol") != -1
False
>>

3、使用 index 方法

字符串对象有一个 index 方法,可以返回指定子串在该字符串中第一次出现的  索引,如果没有找到会抛出异常,因此使用时需要注意捕获。

def is_in(full_str, sub_str):
 try:
 full_str.index(sub_str)
 return True
 except ValueError:
 return False
print(is_in("hello, python", "llo")) # True
print(is_in("hello, python", "lol")) # False

4、使用 count 方法

利用和 index 这种曲线救国的思路,同样我们可以使用 count 的方法来判断。
只要判断结果大于 0 就说明子串存在于字符串中。

def is_in(full_str, sub_str):
 return full_str.count(sub_str) > 0
print(is_in("hello, python", "llo")) # True
print(is_in("hello, python", "lol")) # False

5、通过魔法方法
在第一种方法中,我们使用 in 和 not in 判断一个子串是否存在于另一个字符中,实际上当你使用 in 和 not in 时,Python 解释器会先去检查该对象是否有 __contains__ 魔法方法。
若有就执行它,若没有,Python 就自动会迭代整个序列,只要找到了需要的一项就返回 True。
示例如下;

>>> "hello, python".__contains__("llo")
True
>>>
>>> "hello, python".__contains__("lol")
False
>>>

这个用法与使用 in 和 not in 没有区别,但不排除有人会特意写成这样来增加代码的理解难度。
6、借助 operator
operator模块是python中内置的操作符函数接口,它定义了一些算术和比较内置操作的函数。operator模块是用c实现的,所以执行速度比 python 代码快。
在 operator 中有一个方法 contains 可以很方便地判断子串是否在字符串中。

>>> import operator
>>>
>>> operator.contains("hello, python", "llo")
True
>>> operator.contains("hello, python", "lol")
False
>>>

7、使用正则匹配
说到查找功能,那正则绝对可以说是专业的工具,多复杂的查找规则,都能满足你。
对于判断字符串是否存在于另一个字符串中的这个需求,使用正则简直就是大材小用。

import re
def is_in(full_str, sub_str):
 if re.findall(sub_str, full_str):
 return True
 else:
 return False
print(is_in("hello, python", "llo")) # True
print(is_in("hello, python", "lol")) # False

3.6 海象运算符的三种用法

Python 版本发展非常快,如今最新的版本已经是 Pyhton 3.9,即便如此,有很多人甚至还停留在 3.6 或者 3.7,连 3.8 还没用上。
很多 Python 3.8 的特性还没来得及了解,就已经成为旧知识了,比如今天要说的海象运算符。
海象运算符是在 PEP 572 被提出的,直到 3.8 版本合入发布。
它的英文原名叫 Assignment Expressions ,翻译过来也就是 赋值表达式 ,不过现在大家更普遍地称之为海象运算符,就是因为它长得真的太像海象了。

Python黑魔法手册 2.0 文档第三章:炫技魔法操作【5-6】

第一个用法:if/else
可能有朋友是第一次接触这个新特性,所以还是简单的介绍一下这个海象运算符有什么用?
在 Golang 中的条件语句可以直接在 if 中运算变量的获取后直接对这个变量进行判断,可以让你少写一行代码

import "fmt"
func main() {
 if age := 20;age > 18 {
 fmt.Println("已经成年了")
 }
}

若在 Python 3.8 之前,Python 必须得这样子写

age = 20
if age > 18:
 print("已经成年了")

但有了海象运算符之后,你可以和 Golang 一样(如果你没学过 Golang,那这里要注意,Golang 中的 := 叫短变量声明,意思是声明并初始化,它和 Python 中的 := 不是一个概念)

if (age:= 20) > 18:
 print("已经成年了")

第二个用法:while
在不使用 海象运算符之前,使用 while 循环来读取文件的时候,你也许会这么写

file = open("demo.txt", "r")
while True:
 line = file.readline()
 if not line:
 break
 print(line.strip())

但有了海象运算符之后,你可以这样

file = open("demo.txt", "r")
while (line := file.readline()):
 print(line.strip())

使用它替换以往的无限 while 循环写法更为惊艳
比如,实现一个需要命令行交互输入密码并检验的代码,你也许会这样子写

while True:
 p = input("Enter the password: ")
 if p == "youpassword":
 break

有了海象运算符之后,这样子写更为舒服

while (p := input("Enter the password: ")) != "youpassword":
 continue

第三个用法:推导式
这个系列的文章,几乎每篇都能看到推导式的身影,这一篇依旧如此。
在编码过程中,我很喜欢使用推导式,在简单的应用场景下,它简洁且不失高效。
如下这段代码中,我会使用列表推导式得出所有会员中过于肥胖的人的 bmi 指数

members = [
 {"name": "小五", "age": 23, "height": 1.75, "weight": 72},
 {"name": "小李", "age": 17, "height": 1.72, "weight": 63},
 {"name": "小陈", "age": 20, "height": 1.78, "weight": 82},
]
count = 0
def get_bmi(info):
 global count
 count += 1
 print(f"执行了 {count} 次")
 height = info["height"]
 weight = info["weight"]
 return weight / (height**2)
# 查出所有会员中过于肥胖的人的 bmi 指数
fat_bmis = [get_bmi(m) for m in members if get_bmi(m) > 24]
print(fat_bmis)

输出如下

执行了 1 次
执行了 2 次
执行了 3 次
执行了 4 次
[25.88057063502083]

可以看到,会员数只有 3 个,但是 get_bmi 函数却执行了 4 次,原因是在判断时执行了 3次,而在构造新的列表时又重复执行了一遍。
如果所有会员都是过于肥胖的,那最终将执行 6 次,这种在大量的数据下是比较浪费性能的,因此对于这种结构,我通常会使用传统的for 循环 + if 判断。

fat_bmis = []
# 查出所有会员中过于肥胖的人的 bmi 指数
for m in members:
 bmi = get_bmi(m)
 if bmi > 24:
 fat_bmis.append(bmi)

在有了海象运算符之后,你就可以不用在这种场景下做出妥协。

# 查出所有会员中过于肥胖的人的 bmi 指数
fat_bmis = [bmi for m in members if (bmi := get_bmi(m)) > 24]

最终从输出结果可以看出,只执行了 3 次

执行了 1 次
执行了 2 次
执行了 3 次
[25.88057063502083]

这里仅介绍了列表推导式,但在字典推导式和集合推导式中同样适用。不再演示。
海象运算符,是一个新奇的特性,有不少人觉得这样这种特性会破坏代码的可读性。确实在一个新鲜事物刚出来时是会这样,但我相信经过时间的沉淀后,越来越多的人使用它并享受它带来的便利时,这种争议也会慢慢消失在历史的长河中。

 

版权声明:safedragon 发表于 2022-09-08 20:40:12。
转载请注明:Python黑魔法手册 2.0 文档第三章:炫技魔法操作【5-6】 | 网址导航

暂无评论

暂无评论...