1).Python 迭代器
Python 迭代器
迭代器是一种对象,该对象包含值的可计数数字。
迭代器是可迭代的对象,这意味着您可以遍历所有值。
从技术上讲,在 Python 中,迭代器是实现迭代器协议的对象,它包含方法 __iter__() 和 __next__()。
迭代器 VS 可迭代对象(Iterable)
列表、元组、字典和集合都是可迭代的对象。它们是可迭代的容器,您可以从中获取迭代器(Iterator)。
所有这些对象都有用于获取迭代器的 iter() 方法:
实例
从元组返回一个迭代器,并打印每个值:
mytuple = ("apple", "banana", "cherry") myit = iter(mytuple) print(next(myit)) print(next(myit)) print(next(myit)) #
apple
banana
cherry
甚至连字符串都是可迭代的对象,并且可以返回迭代器:
实例
字符串也是可迭代的对象,包含一系列字符:
mystr = "banana" myit = iter(mystr) print(next(myit)) print(next(myit)) print(next(myit)) print(next(myit)) print(next(myit)) print(next(myit)) # b a n a n a
遍历迭代器
我们也可以使用 for 循环遍历可迭代对象:
实例
迭代元组的值:
mytuple = ("apple", "banana", "cherry") for x in mytuple: print(x)
实例
迭代字符串中的字符:
mystr = "banana" for x in mystr: print(x)
提示:for 循环实际上创建了一个迭代器对象,并为每个循环执行 next() 方法。
创建迭代器
要把对象/类创建为迭代器,必须为对象实现 __iter__() 和 __next__() 方法。
正如您在 Python 类/对象 一章中学到的,所有类都有名为 __init__() 的函数,它允许您在创建对象时进行一些初始化。
__iter__() 方法的作用相似,您可以执行操作(初始化等),但必须始终返回迭代器对象本身。
__next__() 方法也允许您执行操作,并且必须返回序列中的下一个项目。
实例
创建一个返回数字的迭代器,从 1 开始,每个序列将增加 1(返回 1、2、3、4、5 等):
class MyNumbers: def __iter__(self): self.a = 1 return self def __next__(self): x = self.a self.a += 1 return x myclass = MyNumbers() myiter = iter(myclass) print(next(myiter)) print(next(myiter)) print(next(myiter)) print(next(myiter)) print(next(myiter))
StopIteration
如果你有足够的 next() 语句,或者在 for 循环中使用,则上面的例子将永远进行下去。
为了防止迭代永远进行,我们可以使用 StopIteration 语句。
在 __next__() 方法中,如果迭代完成指定的次数,我们可以添加一个终止条件来引发错误:
实例
在 20 个迭代之后停止:
class MyNumbers: def __iter__(self): self.a = 1 return self def __next__(self): if self.a <= 20: x = self.a self.a += 1 return x else: raise StopIteration myclass = MyNumbers() myiter = iter(myclass) for x in myiter: print(x)
2).Python 作用域
变量仅在创建区域内可用。这称为作用域。
局部作用域
在函数内部创建的变量属于该函数的局部作用域,并且只能在该函数内部使用。
全局作用域
在 Python 代码主体中创建的变量是全局变量,属于全局作用域。
全局变量在任何范围(全局和局部)中可用。
Global 关键字
如果您需要创建一个全局变量,但被卡在本地作用域内,则可以使用 global 关键字。
global 关键字使变量成为全局变量。
3).Python 模块
什么是模块?
请思考与代码库类似的模块。
模块是包含一组函数的文件,希望在应用程序中引用。
创建模块
如需创建模块,只需将所需代码保存在文件扩展名为 .py 的文件中:
实例
在名为 mymodule.py 的文件中保存代码:
def greeting(name): print("Hello, " + name)
使用模块
现在,我们就可以用 import 语句来使用我们刚刚创建的模块:
实例
导入名为 mymodule 的模块,并调用 greeting 函数:
import mymodule mymodule.greeting("Bill")
注释:如果使用模块中的函数时,请使用以下语法:
module_name.function_name #可参照上方模块名.功能名
模块中的变量
模块可以包含已经描述的函数,但也可以包含各种类型的变量(数组、字典、对象等):
实例
在文件 mymodule.py 中保存代码:
person1 = { "name": "Bill", "age": 63, "country": "USA" }
实例
导入名为 mymodule 的模块,并访问 person1 字典:
import mymodule a = mymodule.person1["age"] print(a)
为模块命名
您可以随意对模块文件命名,但是文件扩展名必须是 .py。
重命名模块
您可以在导入模块时使用 as 关键字创建别名:
实例
为 mymodule 创建别名 mx:
import mymodule as mx
a = mx.person1["age"]
print(a)
内建模块
Python 中有几个内建模块,您可以随时导入。
实例
导入并使用 platform 模块:
import platform x = platform.system() print(x) #Windows
使用 dir() 函数
有一个内置函数可以列出模块中的所有函数名(或变量名)。dir() 函数:
实例
列出属于 platform 模块的所有已定义名称:
import platform x = dir(platform) print(x)
#
['DEV_NULL', '_UNIXCONFDIR', '_WIN32_CLIENT_RELEASES', '_WIN32_SERVER_RELEASES', '__builtins__', '__cached__', '__copyright__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '__version__', '_comparable_version', '_component_re', '_default_architecture', '_dist_try_harder', '_follow_symlinks', '_ironpython26_sys_version_parser', '_ironpython_sys_version_parser', '_java_getprop', '_libc_search', '_linux_distribution', '_lsb_release_version', '_mac_ver_xml', '_node', '_norm_version', '_parse_release_file', '_platform', '_platform_cache', '_pypy_sys_version_parser', '_release_filename', '_release_version', '_supported_dists', '_sys_version', '_sys_version_cache', '_sys_version_parser', '_syscmd_file', '_syscmd_uname', '_syscmd_ver', '_uname_cache', '_ver_output', '_ver_stages', 'architecture', 'collections', 'dist', 'java_ver', 'libc_ver', 'linux_distribution', 'mac_ver', 'machine', 'node', 'os', 'platform', 'popen', 'processor', 'python_branch', 'python_build', 'python_compiler', 'python_implementation', 'python_revision', 'python_version', 'python_version_tuple', 're', 'release', 'subprocess', 'sys', 'system', 'system_alias', 'uname', 'uname_result', 'version', 'warnings', 'win32_ver']
#
注释:dir() 函数可用于所有模块,也可用于您自己创建的模块。
从模块导入
您可以使用 from 关键字选择仅从模块导入部件。
实例
名为 mymodule 的模块拥有一个函数和一个字典:
def greeting(name): print("Hello, " + name) person1 = { "name": "Bill", "age": 63, "country": "USA" }
实例
仅从模块导入 person1 字典:
from mymodule import person1 print (person1["age"])
提示:在使用 from 关键字导入时,请勿在引用模块中的元素时使用模块名称。示例:person1["age"],而不是 mymodule.person1["age"]。
4).Python 日期
Python 中的日期不是其自身的数据类型,但是我们可以导入名为 datetime 的模块,把日期视作日期对象进行处理。
实例
导入 datetime 模块并显示当前日期:
import datetime x = datetime.datetime.now() print(x)
日期输出
如果我们执行上面的代码,结果将是:
2019-08-14 12:52:55.817273
日期包含年、月、日、小时、分钟、秒和微秒。
datetime 模块有许多方法可以返回有关日期对象的信息。
以下是一些例子,您将在本章稍后详细学习它们:
实例
返回 weekday 的名称和年份:
import datetime x = datetime.datetime.now() print(x.year) print(x.strftime("%A")) #2021 Thursday
%A | Weekday,完整版本 | Wednesday |
创建日期对象
如需创建日期,我们可以使用 datetime 模块的 datetime() 类(构造函数)。
datetime() 类需要三个参数来创建日期:年、月、日。
实例
创建日期对象:
import datetime x = datetime.datetime(2020, 5, 17) print(x)
datetime() 类还接受时间和时区(小时、分钟、秒、微秒、tzone)的参数,不过它们是可选的,默认值为 0,(时区默认为 None)。
strftime() 方法
datetime 对象拥有把日期对象格式化为可读字符串的方法。
该方法称为 strftime(),并使用一个 format 参数来指定返回字符串的格式:
实例
显示月份的名称:
import datetime x = datetime.datetime(2019, 10, 1) print(x.strftime("%B")) #October
所有合法格式代码的参考:
指令 | 描述 | 实例 | TIY |
%a | Weekday,短版本 | Wed | |
%A | Weekday,完整版本 | Wednesday | |
%w | Weekday,数字 0-6,0 为周日 | 3 | |
%d | 日,数字 01-31 | 31 | |
%b | 月名称,短版本 | Dec | |
%B | 月名称,完整版本 | December | |
%m | 月,数字01-12 | 12 | |
%y | 年,短版本,无世纪 | 18 | |
%Y | 年,完整版本 | 2018 | |
%H | 小时,00-23 | 17 | |
%I | 小时,00-12 | 05 | |
%p | AM/PM | PM | |
%M | 分,00-59 | 41 | |
%S | 秒,00-59 | 08 | |
%f | 微妙,000000-999999 | 548513 | |
%z | UTC 偏移 | +0100 | 试一试 |
%Z | 时区 | CST | 试一试 |
%j | 天数,001-366 | 365 | |
%U | 周数,每周的第一天是周日,00-53 | 52 | |
%W | 周数,每周的第一天是周一,00-53 | 52 | |
%c | 日期和时间的本地版本 | Mon Dec 31 17:41:00 2018 | |
%x | 日期的本地版本 | 12/31/18 | |
%X | 时间的本地版本 | 17:41:00 | |
%% | A % character | % |
5).Python JSON
JSON 是用于存储和交换数据的语法。
JSON 是用 JavaScript 对象表示法(JavaScript object notation)编写的文本。
Python 中的 JSON
Python 有一个名为 json 的内置包,可用于处理 JSON 数据。
实例
导入 json 模块:
import json
解析 JSON - 把 JSON 转换为 Python
若有 JSON 字符串,则可以使用 json.loads() 方法对其进行解析。
结果将是 Python 字典。
实例
把 JSON 转换为 Python:
import json # 一些 JSON: x = '{ "name":"Bill", "age":63, "city":"Seatle"}' # 解析 x: y = json.loads(x) # 结果是 Python 字典: print(y["age"])
把 Python 转换为 JSON
若有 Python 对象,则可以使用 json.dumps() 方法将其转换为 JSON 字符串。
实例
把 Python 转换为 JSON:
import json # Python 对象(字典): x = { "name": "Bill", "age": 63, "city": "Seatle" } # 转换为 JSON: y = json.dumps(x) # 结果是 JSON 字符串: print(y)
您可以把以下类型的 Python 对象转换为 JSON 字符串:
- dict
- list
- tuple
- string
- int
- float
- True
- False
- None
实例
将 Python 对象转换为 JSON 字符串,并打印值:
import json print(json.dumps({"name": "Bill", "age": 63})) #字典 print(json.dumps(["apple", "bananas"])) #列表 print(json.dumps(("apple", "bananas"))) #元组 print(json.dumps("hello")) print(json.dumps(42)) print(json.dumps(31.76)) print(json.dumps(True)) print(json.dumps(False)) print(json.dumps(None))
当 Python 转换为 JSON 时,Python 对象会被转换为 JSON(JavaScript)等效项:
Python | JSON |
dict | Object |
list | Array |
tuple | Array |
str | String |
int | Number |
float | Number |
True | true |
False | false |
None | null |
实例
转换包含所有合法数据类型的 Python 对象:
import json x = { "name": "Bill", "age": 63, "married": True, "divorced": False, "children": ("Jennifer","Rory","Phoebe"), "pets": None, "cars": [ #列表 {"model": "Porsche", "mpg": 38.2}, {"model": "BMW M5", "mpg": 26.9} ] } print(json.dumps(x)) # {"name": "Bill", "age": 63, "married": true, "divorced": false, "children": ["Jennifer", "Rory", "Phoebe"], "pets": null, "cars": [{"model": "Porsche", "mpg": 38.2}, {"model": "BMW M5", "mpg": 26.9}]}
#
格式化结果
上面的实例打印一个 JSON 字符串,但它不是很容易阅读,没有缩进和换行。
json.dumps() 方法提供了令结果更易读的参数:
实例
使用 indent 参数定义缩进数:
json.dumps(x, indent=4)
{
"name": "Bill",
"age": 63,
"married": true,
"divorced": false,
"children": [
"Jennifer",
"Rory",
"Phoebe"
],
"pets": null,
"cars": [
{
"model": "Porsche",
"mpg": 38.2
},
{
"model": "BMW M5",
"mpg": 26.9
}
]
}
您还可以定义分隔符,默认值为(", ", ": "),这意味着使用逗号和空格分隔每个对象,使用冒号和空格将键与值分开:
实例
使用 separators 参数来更改默认分隔符:
json.dumps(x, indent=4, separators=(". ", " = "))
{
"name" = "Bill".
"age" = 63.
"married" = true.
"divorced" = false.
"children" = [
"Jennifer".
"Rory".
"Phoebe"
].
"pets" = null.
"cars" = [
{
"model" = "Porsche".
"mpg" = 38.2
}.
{
"model" = "BMW M5".
"mpg" = 26.9
}
]
}
对结果排序
json.dumps() 方法提供了对结果中的键进行排序的参数:
实例
使用 sort_keys 参数来指定是否应对结果进行排序:
json.dumps(x, indent=4, sort_keys=True)
{
"age": 63,
"cars": [
{
"model": "Porsche",
"mpg": 38.2
},
{
"model": "BMW M5",
"mpg": 26.9
}
],
"children": [
"Jennifer",
"Rory",
"Phoebe"
],
"divorced": false,
"married": true,
"name": "Bill",
"pets": null
}
6).Python RegEx
RegEx 或正则表达式是形成搜索模式的字符序列。
RegEx 可用于检查字符串是否包含指定的搜索模式。
RegEx 模块
Python 提供名为 re 的内置包,可用于处理正则表达式。
导入 re 模块:
import re
Python 中的 RegEx
导入 re 模块后,就可以开始使用正则表达式了:
实例
检索字符串以查看它是否以 "China" 开头并以 "country" 结尾:
import re
txt = "China is a great country"
x = re.search("^China.*country$", txt)
RegEx 函数
re 模块提供了一组函数,允许我们检索字符串以进行匹配:
函数 | 描述 |
findall | 返回包含所有匹配项的列表 |
search | 如果字符串中的任意位置存在匹配,则返回 Match 对象 |
split | 返回在每次匹配时拆分字符串的列表 |
sub | 用字符串替换一个或多个匹配项 |
元字符
元字符是具有特殊含义的字符:
字符 | 描述 | 示例 | TIY |
[] | 一组字符 | "[a-m]" | |
\ | 示意特殊序列(也可用于转义特殊字符) | "\d" | |
. | 任何字符(换行符除外) | "he..o" | |
^ | 起始于 | "^hello" | |
$ | 结束于 | "world$" | |
* | 零次或多次出现 | "aix*" | |
+ | 一次或多次出现 | "aix+" | |
{} | 确切地指定的出现次数 | "al{2}" | |
| | 两者任一 | "falls|stays" | |
() | 捕获和分组 |
特殊序列
特殊序列指的是 \ 后跟下表中的某个字符,拥有特殊含义:
字符 | 描述 | 示例 | TIY |
\A | 如果指定的字符位于字符串的开头,则返回匹配项 | "\AThe" | |
\b | 返回指定字符位于单词的开头或末尾的匹配项 | r"\bain" r"ain\b" | |
\B | 返回指定字符存在的匹配项,但不在单词的开头(或结尾处) | r"\Bain" r"ain\B" | |
\d | 返回字符串包含数字的匹配项(数字 0-9) | "\d" | |
\D | 返回字符串不包含数字的匹配项 | "\D" | |
\s | 返回字符串包含空白字符的匹配项 | "\s" | |
\S | 返回字符串不包含空白字符的匹配项 | "\S" | |
\w | 返回一个匹配项,其中字符串包含任何单词字符 (从 a 到 Z 的字符,从 0 到 9 的数字和下划线 _ 字符) | "\w" | |
\W | 返回一个匹配项,其中字符串不包含任何单词字符 | "\W" | |
\Z | 如果指定的字符位于字符串的末尾,则返回匹配项 | "Spain\Z" |
集合(Set)
集合(Set)是一对方括号 [] 内的一组字符,具有特殊含义:
集合 | 描述 | 试一试 |
[arn] | 返回一个匹配项,其中存在指定字符(a,r 或 n)之一 | |
[a-n] | 返回字母顺序 a 和 n 之间的任意小写字符匹配项 | |
[^arn] | 返回除 a、r 和 n 之外的任意字符的匹配项 | |
[0123] | 返回存在任何指定数字(0、1、2 或 3)的匹配项 | |
[0-9] | 返回 0 与 9 之间任意数字的匹配 | |
[0-5][0-9] | 返回介于 0 到 9 之间的任何数字的匹配项 | |
[a-zA-Z] | 返回字母顺序 a 和 z 之间的任何字符的匹配,小写或大写 | |
[+] | 在集合中,+、*、.、|、()、$、{} 没有特殊含义,因此 [+] 表示:返回字符串中任何 + 字符的匹配项 |
findall() 函数
findall() 函数返回包含所有匹配项的列表。
实例
打印所有匹配的列表:
import re str = "China is a great country" x = re.findall("a", str) print(x) #['a', 'a', 'a']
这个列表以被找到的顺序包含匹配项。列表元素共3个
如果未找到匹配项,则返回空列表:
实例
如果未找到匹配,则返回空列表:
import re str = "China is a great country" x = re.findall("USA", str) print(x) #[]
search() 函数
search() 函数搜索字符串中的匹配项,如果存在匹配则返回 Match 对象。
如果有多个匹配,则仅返回首个匹配项:
实例
在字符串中搜索第一个空白字符:
import re str = "China is a great country" x = re.search("\s", str) print("The first white-space character is located in position:", x.start()) #The first white-space character is located in position: 5
如果未找到匹配,则返回值 None:
实例
进行不返回匹配的检索:
import re str = "China is a great country" x = re.search("USA", str) print(x) #None
split() 函数
split() 函数返回一个列表,其中字符串在每次匹配时被拆分:
实例
在每个空白字符处进行拆分:
import re str = "China is a great country" x = re.split("\s", str) print(x) #['China', 'is', 'a', 'great', 'country']
您可以通过指定 maxsplit 参数来控制出现次数:
实例
仅在首次出现时拆分字符串:
import re str = "China is a great country" x = re.split("\s", str, 1) print(x) #['China', 'is a great country']
sub() 函数
sub() 函数把匹配替换为您选择的文本:
实例
用数字 9 替换每个空白字符:
import re str = "China is a great country" x = re.sub("\s", "9", str) print(x) #China9is9a9great9country
您可以通过指定 count 参数来控制替换次数:
实例
替换前两次出现:
import re str = "China is a great country" x = re.sub("\s", "9", str, 2) print(x) #China9is9a great country
Match 对象
Match 对象是包含有关搜索和结果信息的对象。
注释:如果没有匹配,则返回值 None,而不是 Match 对象。
实例
执行会返回 Match 对象的搜索:
import re str = "China is a great country" x = re.search("a", str) print(x) # 将打印一个对象 <re.Match object; span=(4, 5), match='a'>
Match 对象提供了用于取回有关搜索及结果信息的属性和方法:
- span() 返回的元组包含了匹配的开始和结束位置
- .string 返回传入函数的字符串
- group() 返回匹配的字符串部分
实例
打印首个匹配出现的位置(开始和结束位置)。
正则表达式查找以大写 "C" 开头的任何单词:
import re str = "China is a great country" x = re.search(r"\bC\w+", str) print(x.span()) #返回的元组包含了匹配的开始和结束位置(0, 5)
实例
打印传入函数的字符串:
import re str = "China is a great country" x = re.search(r"\bC\w+", str) print(x.string) #返回传入的字符串,China is a great country
实例
打印匹配的字符串部分。
正则表达式查找以大写 "C" 开头的任何单词:
import re str = "China is a great country" x = re.search(r"\bC\w+", str) print(x.group()) #返回字符串部分,China
注释:如果没有匹配项,则返回值 None,而不是 Match 对象。