Python3 - 开始python编程(八)

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 忽略转义序列。这在制作正则表达式模式时很有用。

我本来想跳过的是字符串前面的ff消除了在字符串末尾添加.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 章

5. 数据结构-Python 3. 7.3 文档

第 4. 7 章

4. 更多控制流工具-Python 3. 7.3 文档

和第 7.1 章

7. 输入和输出-Python 3. 7.3 文档

下一步是什么

接下来是与处理代码错误有关的所有内容。我们所有人都有错误-有时您对问题有预见性,并且您了解如何处理问题,而其他时候则无法解决。敬请期待!同时,练习您学到的知识和创造的知识。

Rating: