Python3 - 开始python编程(八)
格式化技术,列表推导和 lambda 在上一篇文章中,了解了类以及如何创建和销毁它们。我们还研究了如何针对不同用例覆盖子类中的特定功能。今天,我们将介绍字符串格式,列表推导和 lambda。
格式化
到目前为止,我们一直在使用加法运算符连接字符串。虽然这适用于简单的字符串,但扩展性不好。我们将介绍几种不同的格式化选项,因此当您的程序需要时,您可以自己决定最佳的解决方案。
处理字符串的第一种方法是使用%。这是许多用 Python 2 编写的程序执行此操作的方式。
1
2
3
4
5
6
dog_name = "Spot"
owner_name = "James"
dog_age = 3
print("%s is %d years old and %s is his master." % (dog_name, dog_age, owner_name))
# displays "Spot is 3 years old and James is his master."
我们有三个变量:”dog_name”,”owner_name”和”dog_age”。我们使用%格式使用这三个变量来构建句子。
Python 会在字符串中查找“%”符号,后跟一个字母,可能是”s”,”d”或”f”。它们分别代表字符串,十进制和浮点数。在字符串的末尾,我们包含一个’%’符号,后跟一个元组的变量,Python 应该使用这些变量来替换该字符串中使用的转义序列。
在上面的示例中,我故意排除了浮点数,因为它们可能会产生意外的结果。
1
2
3
4
5
6
7
8
9
10
products = ["Vanilla", "Chocolate", "Strawberry"]
costs = [2.99, 3.99, 3.99]
for i in range(0, 3):
print("%s - $%f" % (products[i], costs[i]))
# Displays
# Vanilla - $2.990000
# Chocolate - $3.990000
# Strawberry - $3.990000
等等,这不对-应该只显示两位小数,而不是六个小数。发生了什么?
默认情况下,“%f”显示六个小数位。我们可以使用%2f 代替%f 来覆盖它。 “。”是小数点,”2”是在小数点后显示的小数位数。
如果将 2 放在小数点的前面,则$会在整数的前面保留足够的空格。
1
2
3
4
5
6
7
8
9
10
products = ["Vanilla", "Chocolate", "Strawberry"]
costs = [2.99, 3.99, 3.99]
for i in range(0, 3):
print("%s - $%.2f" % (products[i], costs[i]))
# Displays
# Vanilla - $2.99
# Chocolate - $3.99
# Strawberry - $3.99
我们还可以通过使用字符串对齐来使其更简洁。
1
2
3
4
5
6
7
8
9
10
products = ["Vanilla", "Chocolate", "Strawberry"]
costs = [2.99, 3.99, 3.99]
for i in range(0, 3):
print("%-10s - $%.2f" % (products[i], costs[i]))
# Displays
# Vanilla - $2.99
# Chocolate - $3.99
# Strawberry - $3.99
现在,我们使用%-10s 将第一个字符串填充十个字符。”Vanilla”和 Chocolate”周围增加了空格,因此”Vanilla”与”Strawberry”一样长。如果我们不包含-
号,我们将在字符串的前面添加足够的空间,以使 Vanilla 和 Chocolate 与草莓草莓对齐。
1
2
3
4
5
6
7
8
9
10
11
products = ["Vanilla", "Chocolate", "Strawberry"]
costs = [2.99, 3.99, 3.99]
for i in range(0, 3):
print("%10s - $%.2f" % (products[i], costs[i]))
# Displays
# Vanilla - $2.99
# Chocolate - $3.99
# Strawberry - $3.99
下一个字符串格式化程序是.format
。
1
2
3
4
5
6
dog_name = "Spot"
owner_name = "James"
dog_age = 3
print("{} is {} years old and {} is his master.".format(dog_name, dog_age, owner_name))
# displays "Spot is 3 years old and James is his master."
.format 是格式化字符串的“新方法”,它使格式化字符串更易于阅读。
与其像以前那样搜索“%”符号,不如将”{}”替换为格式函数中传递的变量。在这个例子中,每个占位符的替换顺序与变量在.format 中的显示顺序相同。
如果有多个占位符应使用同一个变量填充,则可以将数字放在大括号中,以表示参数在.format 中的位置。例如{0},{1},{2}。在变量多次使用的任何地方,都可以在花括号中重复使用其位置。
如果需要对浮点值进行任何格式设置,则可以使用以下语法获得与上述相同的结果:{0:2.2f}
。冒号将变量与格式分开。 2.2f
之前最多放置两个空格小数点,小数点后最多两个零。
您还可以命名位置:
1
2
3
4
5
lavor = "chocolate"
name = "Samantha"
print("{name}'s favorite flavor is {flavor}.".format(flavor=flavor, name=name))
# Displays "Samantha's favorite flavor is chocolate."
.format
还有一个窍门,但前提是您使用命名位置。
1
2
3
4
flavor = "chocolate"
name = "Samantha"
print("{name}'s favorite flavor is {flavor}.".format(**locals()))
**locals()是一个处理程序(或指向指针的指针),它查看执行时可用的所有变量。它扫描命名的位置并查找具有相同名称的变量。如果找到一个,则将命名位置替换为找到的变量。如果没有,您将收到一个”KeyError”。这有助于使代码保持简单。
还有更多内容-我可以写整篇有关格式化的文章-但现在,在继续列出理解之前,我们将讨论另一种类型的格式化程序。
转义序列有多种类型,\t
制表符,\s
是空格,\\
是反斜杠,\"
是双引号,\'
是单引号。仅当在以相同引号类型包装的字符串中使用双引号或单引号时,引号才是必需的。
要忽略这些,我们可以使用原始字符串。
1
"This is how you make a new line: n"# can also be typed asr"This is how you make a new line: n"
第一个引号前的r
告诉 Python 忽略转义序列。这在制作正则表达式模式时很有用。
我本来想跳过的是字符串前面的f
。 f
消除了在字符串末尾添加.format
的需要,并寻找要插入到字符串中的局部变量。
1
2
3
4
lavor = "chocolate"
name = "Samantha"
print(f"{name}'s favorite flavor is {flavor}.")
看看看起来有多干净?它可以正常工作-将其复制并粘贴到编辑器中以供自己查看。
在大括号内键入内容时,某些编辑器(例如 PyCharm)可以为您提供变量名。这样可以节省时间,其他开发人员也喜欢阅读这样的代码。
列表解析
我们可以用列表来做各种很酷的事情。列表推导允许我们从字符串中创建列表,或者通过程序生成编号列表:
1
2
3
4
hello_letters = [letter for letter in "hello"]
print(hello_letters)
# ['h', 'e', 'l', 'l', 'o']
在这里我们可以看到我们遍历”hello”中的所有字符并创建一个列表,其中每个字母都是列表中的一个项目。
您还可以在列表推导中使用条件,仅返回所需的值。
1
2
3
4
5
vowels = ['a', 'e', 'i', 'o', 'u']
hello_vowels = [x for x in "hello" if x in vowels]
print(hello_vowels)
# ['e', 'o']
在这里,我们遍历”hello”一词中的每个字母。如果当前字母”x”也位于“元音”列表中,则应将其包括在”hello_vowels”列表中。最后,我们打印列表,看到仅将元音从”hello”中拉出。
这里有一个问题:如果我们要检查的单词是”HELLO”,我们将不会从中取出任何元音,因为在编程中”E”不等于”e” —我们正在检查字节,而不是英文字符。有关更多信息,请参见ASCII 表。
要解决此错误,我们可以在列表理解中执行.lower()
函数,该函数属于所有字符串和字符类型。
1
2
3
4
5
vowels = ['a', 'e', 'i', 'o', 'u']
hello_vowels = [x for x in "HELLO".lower() if x in vowels]
print(hello_vowels)
# ['e', 'o']
但是我们引入了一个新问题。如果我们想要这些字母的大写字母怎么办?在这种情况下,我们将大写元音添加到“元音”列表中,并从”HELLO”字符串中删除”.lower()”。
让我们更进一步:
1
2
3
4
5
vowels = ['a', 'e', 'i', 'o', 'u']
types = ["Vowel" if i in vowels else "Consonant" for i in "hello"]
print(types)
# ['Consonant', 'Vowel', 'Consonant', 'Consonant', 'Vowel']
在这里,我们可以确定单词中的字母是辅音还是元音,并创建一个列表,以后可以将其用于其他内容。
Lambda 表达式
Lambda 是匿名函数。也就是说,它们没有功能签名。 Lambda 可以具有任意数量的参数,但始终执行相同的表达式:
1
2
3
4
5
6
7
def add_one(x):
return x + 1
add_another = lambda x: x + 1
print(add_one(5)) # 6
print(add_another(3)) # 4
创建 lambda 时,您可以像传递变量一样传递它。但是,它打算用作高阶函数的参数。高阶函数将函数作为其参数之一,或者将结果返回。
以下是一些高阶函数的示例,并描述了它们的作用:
filter(func,x)
—过滤满足表达式 fr 的元素清单
1
2
3
4
numbers = [1, 2, 3, 4, 5]
evens = list(filter(lambda x: (x % 2 ==0), numbers))
# [2, 4]
map(func,x)
-对列表中的每个项目执行一个表达式
1
2
3
4
numbers = [2, 4, 6, 8, 10]
halfs = list(map(lambda x: x / 2, numbers))
# [1.0, 2.0, 3.0, 4.0, 5.0]
Lambda 很棘手,尽管它们为您节省了您可能需要做的大量键入工作,但它们会使您的代码难以理解。使用 lambda 时,请尝试确保您的代码具有描述性和显性性。
摘要
今天,我们讨论了格式化技术,列表推导和 lambda。也许我应该将其分解为单独的部分,但是我认为这足以让您了解每个部分的要点。
我建议回顾一下以前的代码并使用字符串格式,以获取一些使用经验。尝试将一些使用列表的旧示例转换为列表推导,以获得相同的结果。对于 lambda,我强烈建议与他们一起玩耍,以更好地了解它们的工作方式。
建议阅读
第 5. 1、5. 3 和 5. 6 章
第 4. 7 章
和第 7.1 章
下一步是什么
接下来是与处理代码错误有关的所有内容。我们所有人都有错误-有时您对问题有预见性,并且您了解如何处理问题,而其他时候则无法解决。敬请期待!同时,练习您学到的知识和创造的知识。