# 全民一起学python-提高篇 **Repository Path**: iammyself001/All-the-people-learn-python-improve ## Basic Information - **Project Name**: 全民一起学python-提高篇 - **Description**: 全民一起学python-提高篇 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2023-03-13 - **Last Updated**: 2023-11-15 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README * 提高篇 ** 导言 *** [[https://mp.weixin.qq.com/s?__biz=MzU1OTM3ODQ0MA==&mid=2247503602&idx=1&sn=fa0c02d68a2e97c42f4d6415d5b7cbb3&chksm=fc1ab795cb6d3e83fc5db6112fb26b1352a989b2ad5b6e7c3d72c68146062cb3ab9bda3a020e&scene=21&token=1258783393&lang=zh_CN#wechat_redirect][第0回 书到深处真如铁,而今迈步从头越]] ** 第一卷 数据类型与语法细节 *** [[https://mp.weixin.qq.com/s?__biz=MzU1OTM3ODQ0MA==&mid=2247503602&idx=2&sn=04e169688dfa4e2200441c3af4e743fc&chksm=fc1ab795cb6d3e83dd16649d1498909c92b48f05025815ef23b6d4f1b6c3e84cf97cc8a551d0&scene=21&token=1258783393&lang=zh_CN#wechat_redirect][第1回:集成化环境面面俱到,Pycharm软件无所不包]] *** [[https://mp.weixin.qq.com/s?__biz=MzU1OTM3ODQ0MA==&mid=2247503602&idx=3&sn=aefd41675bd1b774b2c70272de722f01&chksm=fc1ab795cb6d3e834e090cd5b052cbe991e3a8c17ba58dab4dfc4925dd3b5ddbb1ff8c5e2eb5&scene=21&token=1258783393&lang=zh_CN#wechat_redirect][第2回:模块导入需先运行,巧用name规范主宾]] **** import机制 1.导入即执行 2.何时导入何时执行 3.重复导入不再执行 **** __name__ 每次运行 python 程序(无论是独立运行还是被其他程序 import), Python 都会为程序创建一个 *__name__*,并且为它赋值 > 1.独立运行 "__name__" 被赋值”*__main*“ > 2.被 import "__name__" 被赋值 该模块的名字(就是把 .py 去掉的部分) **** __file__ 本模块的路径 *** [[https://mp.weixin.qq.com/s?__biz=MzU1OTM3ODQ0MA==&mid=2247503602&idx=4&sn=167aa7d89f07c45987a6c24450cf2280&chksm=fc1ab795cb6d3e83e37ea9e296051ce8ac49e02aa1fc363ce198e738d8c0142ac4d2c7e52f97&scene=21#wechat_redirect][第三回:包结构整合发布多模块,MatPlotLib轻松绘制统计图]] **** Package 将许多 python 程序放到一个文件夹中,便可以将该文件夹作为第三方库 发布,这个文件就是 *包* #+ATTR_HTML: :width 300px #+ATTR_ORG: :width 400 [[./picture/第3回package/引入package.jpg]] 严格意义上,并不是所有目录都是 python 包,只有 /__init__.py/ 的目录才算 python 包(python 3.3之前必须的) #+BEGIN_SRC Bash # python 3.3以前需要在包文件夹创建 > touch __init__.py # __init__.py 里面的代码是 当这个包被导入的时候,自动执行 #+END_SRC **** __main.py__ 包的主程序入口 #+BEGIN_SRC # 需要将 执行文件入口的 python 文件改成 __main__.py 然后打包 > zip -r mymath.zip mymath > tree mymath.zip ├── b.py ├── c.py └── __main__.py # 给别人zip文件就能执行 > python ./mymath.zip #+END_SRC **** Linux 上python函数库位置 #+BEGIN_SRC > python --version > cd /usr/lib/python3.10 > cd /usr/lib/python3.10/site-packages # 这个是第三方模块位置 #+END_SRC **** matplotlib #+BEGIN_SRC # 散点图 import matplotlib.pyplot as plt # 支持中文 plt.rcParams['font.sans-serif'] = ['fangsong'] plt.rcParams['axes.unicode_minus'] = False # plt.grid() #添加网格 # plt.title("标题") #添加标题 weight = [68, 25, 60, 65, 20, 128, 60 , 37, 50] power = [90, 27, 88, 72, 80, 15, 66, 68, 57] # plt.xlabel("横轴标题") # plt.ylabel("纵轴标题") plt.scatter(weight, power, marker='*') plt.show() #+END_SRC #+attr_html: :width 100px #+attr_latex: :width 100px #+ATTR_ORG: :width 10% [[./picture/第3回package/marker.jpg]] ***** 设置颜色 #+ATTR_ORG: :width 10% [[./picture/第3回package/color.jpg]] *** [[https://mp.weixin.qq.com/s?__biz=MzU1OTM3ODQ0MA==&mid=2247503602&idx=5&sn=9729f5a7d3f2435bcf1ea9880cefe85d&chksm=fc1ab795cb6d3e837b51330ad3274ee015f82cef6282666f82bd4f4a8a14f05eff50e984f067&scene=21#wechat_redirect][第4回:按名字传参数对号入座,用星号代列表长短自由]] *** [[https://mp.weixin.qq.com/s?__biz=MzU1OTM3ODQ0MA==&mid=2247503602&idx=7&sn=0268df76741869542c7784914bccce27&chksm=fc1ab795cb6d3e8308b033776247bb63862120d9b577a5d66dba2bf4256e30e1fd2936b6996a&scene=21#wechat_redirect][第6回:decimal做精算优于round,format调格式胜过其他]] ***** 四舍五入 ****** [不推荐] round(原数值, 保留小数点位数) #+BEGIN_SRC >>> round(3.467) 3 >>> round(3.467, 2) 3.47 #+END_SRC ****** [推荐] Decimal对象 标准模块 decimal, 内置多种专用于高精度十进制计算的工具 Decimal类,可以创建“真正的”十进制数字 #+BEGIN_SRC from decimal import Decimal a = Decimal('2.37') # 参数必须是字符串 b = a + Decimal("0.34") # 这里b 是 Decimal对象 print(b) # 如果需要转换 c = int(b) d = float(b) #+END_SRC ***** 格式输出(显示) #+BEGIN_SRC format (原数值, "格式说明") #+END_SRC #+BEGIN_SRC python x = 14/41 print(x) a = format(x, "0.2f") print(a) print("YBX is the most handsome man") #+END_SRC ***** 正负无穷 #+BEGIN_SRC float('inf') float('-inf') #+END_SRC *** [[https://mp.weixin.qq.com/s?__biz=MzU1OTM3ODQ0MA==&mid=2247503601&idx=1&sn=6f7f9549dda35825cf436e5ead8f0bf8&chksm=fc1ab796cb6d3e8056c6c2d7983b18645f3bf3ddd8cddebd1a0713670dbeedb0727145915fd9&scene=21#wechat_redirect][第8回:时间流逝不过是数字加减,逻辑真假也无非零一相间]] ***** time模块 提供了各种_基础性_的时间操作工具, #+BEGIN_SRC python :results output from time import time s = time() #以浮点数形式返回当前时间 print(s) #+END_SRC #+RESULTS: : 1679065546.6171381 ******* 时间戳使用 #+begin_src python :results output import time # 使用时间戳 # 计算循环时间 t1 = time.time() s = 0; for i in range(100000): s += i; t2 = time.time() t = (t2 - t1) * 1000 print(f"循环计算结束,耗时{t}毫秒") #+end_src #+RESULTS: : 循环计算结束,耗时10.241508483886719毫秒 ***** datetime模块 跟方便灵活的日期时间工具 #+begin_src python :results output from datetime import datetime # 设置时间 h1 = datetime(2021, 10, 1, 10, 1) print(h1) # 获取当前时间 now = datetime.now() print(f"当前时间是{now}") # 调用年属性 print(f"年的属性:{now.year}") # 调用月属性 print(f"月的属性:{now.month}") # 调用日属性 print(f"日的属性:{now.day}") # 调用小时属性 print(f"小时的属性:{now.hour}") # 调用分钟属性 print(f"分钟的属性:{now.minute}") # 调用秒属性 print(f"秒的属性:{now.second}") # 计算时间差 timedelta d1 = datetime(1654, 5, 4, 3, 0) d2 = datetime(1722, 12, 20, 2, 54) #+end_src #+RESULTS: : 2021-10-01 10:01:00 : 当前时间是2023-03-17 23:40:19.905032 : 年的属性:2023 : 月的属性:3 : 日的属性:17 : 小时的属性:23 : 分钟的属性:40 : 秒的属性:19 *** [[https://mp.weixin.qq.com/s?__biz=MzU1OTM3ODQ0MA==&mid=2247503601&idx=2&sn=35884a6ec55f554025d006c82666ce7f&chksm=fc1ab796cb6d3e806efe9a7c22b06e6a88d2144b6e52e287610827e7935ef9e1ab82114f58c5&scene=21#wechat_redirect][第9回:with块管理文件显专业,try结构临危不乱解异常]] #+begin_src python :results output file_name = input("请输入要统计的数据文件名:") try: f = open(file_name, encoding="gb18030") all_data = f.readlines() s = 0 for i in all_data: s += float(i) a = s / len(all_data) print(f"该文件数据平均值为{round(a, 2)}") f.close() except Exception as e: print("发生意外{e}") #+end_src #+RESULTS: ** 第二卷 深入理解各种容器 *** 第11回:数据类型有可变有不可变,判断相同或等号或用 is **** 内存方案 1.为了提高程序执行效率,python *启动程序时* 将 /-5~256/ 常用的小整数创建好,并放到内存固定位置。 2.字符串:首先检测内存中是否已经存在相同内容的字符串对象,如果存在直接使用该字符串的地址,否则创建新的字符串,提高效率 #+begin_src 一旦字符串中包含特殊符号(包括中文)(英文,数字,_),即使已经存在相同内容的字符串,python也会创建新字符串对象 #+end_src 3. .extend()是在原有基础上扩容 + 是重新开辟一个新的存储区 *** 第12回:随机抽样只需一个函数,列表排序可以自定规则 **** 修改列表 想修改列表中的元素不能使用 for in #+begin_src python :results output price = [1000, 800, 1200, 300] for i in price: i = i*7 print(price) #+end_src #+RESULTS: : [1000, 800, 1200, 300] 但是使用 while 循环是可以的 #+begin_src python :results output price = [1000, 800, 1200, 300] i = 0 while i < len(price): price[i] = price[i]*7 i+=1 print(price) #+end_src #+RESULTS: : [7000, 5600, 8400, 2100] **** 列表排序 list.sort() ***** key自定义排序 key 排序时候先将列表中每个元素分别代入该函数,得到返回结果;然后根据返回结果大小对列表元素排序 #+begin_src python :results output # 根据绝对值排序 # 使用 abs() 函数排序 a = [5, 0, -23, 2] a.sort() print(a) a.sort( key=abs ) print(a) #+end_src #+RESULTS: : [-23, 0, 2, 5] : [0, 2, 5, -23] 自定义函数排序 #+begin_src python :results output def degree_order( s ): if '学士' == s: return 0 elif '硕士' == s: return 1 elif '博士' == s: return 2 else: return -1 names = ["学士", "硕士", "博士", "学士", "博士"] names.sort(key=degree_order) # 这里不用写 degree_order的形参 print(names) names.sort(key=degree_order, reverse=True) print(names) #+end_src #+RESULTS: : ['学士', '学士', '硕士', '博士', '博士'] : ['博士', '博士', '硕士', '学士', '学士'] 使用容器(字典、列表等)替代多分支判断结构 #+begin_src python :results output d={"学士":0, "硕士":1, "博士":2} print(d['硕士']) #+end_src #+RESULTS: : 1 #+begin_src python :results output d={"学士":0, "硕士":1, "博士":2} def degree_order( s ): t = s[1] return d[t] names = [["YBX", "学士"], ["小明", "学士"], ["小红", "博士"], ["小方", "硕士"], ["小刚", "硕士"]] names.sort(key=degree_order) print(names) #+end_src #+RESULTS: : [['YBX', '学士'], ['小明', '学士'], ['小方', '硕士'], ['小刚', '硕士'], ['小红', '博士']] 使用lambda表达式 #+begin_src python :results output d={"学士":0, "硕士":1, "博士":2} names = [["YBX", "学士"], ["小明", "学士"], ["小红", "博士"], ["小方", "硕士"], ["小刚", "硕士"]] print(names) names.sort(key=lambda x:d[x[1]]) print(names) #+end_src #+RESULTS: : [['YBX', '学士'], ['小明', '学士'], ['小红', '博士'], ['小方', '硕士'], ['小刚', '硕士']] : [['YBX', '学士'], ['小明', '学士'], ['小方', '硕士'], ['小刚', '硕士'], ['小红', '博士']] sort是对列表本身进行排序,如果想得到列表sort前的y模样可以使用 list.copy() 方法,将列表完整内容复制一份存放到另外内存中 #+begin_src python :results output d={"学士":0, "硕士":1, "博士":2} names = [["YBX", "学士"], ["小明", "学士"], ["小红", "博士"], ["小方", "硕士"], ["小刚", "硕士"]] names_b = names names_c = names.copy() print(f"names的原始数据:{names}") names.sort(key=lambda x:d[x[1]]) print(f"names的值是:{names}") print(f"names_b的值:{names_b}") print(f"names_c的值:{names_c}") #+end_src #+RESULTS: : names的原始数据:[['YBX', '学士'], ['小明', '学士'], ['小红', '博士'], ['小方', '硕士'], ['小刚', '硕士']] : names的值是:[['YBX', '学士'], ['小明', '学士'], ['小方', '硕士'], ['小刚', '硕士'], ['小红', '博士']] : names_b的值:[['YBX', '学士'], ['小明', '学士'], ['小方', '硕士'], ['小刚', '硕士'], ['小红', '博士']] : names_c的值:[['YBX', '学士'], ['小明', '学士'], ['小红', '博士'], ['小方', '硕士'], ['小刚', '硕士']] sorted(列表名, key, reverse) 函数将指定列表复制之后,对复制的新列表排序,不修改原列表 #+begin_src python :results output d={"学士":0, "硕士":1, "博士":2} names = [["YBX", "学士"], ["小明", "学士"], ["小红", "博士"], ["小方", "硕士"], ["小刚", "硕士"]] print(f"names的原始数据:{names}") names_a = sorted(names, key=lambda x:d[x[1]]) print(f"names的值是{names}") print(f"names_a的值是{names_a}") #+end_src #+RESULTS: : names的原始数据:[['YBX', '学士'], ['小明', '学士'], ['小红', '博士'], ['小方', '硕士'], ['小刚', '硕士']] : names的值是[['YBX', '学士'], ['小明', '学士'], ['小红', '博士'], ['小方', '硕士'], ['小刚', '硕士']] : names_a的值是[['YBX', '学士'], ['小明', '学士'], ['小方', '硕士'], ['小刚', '硕士'], ['小红', '博士']] **** random函数 ***** random.shuffle(列表名) 可以对列表内容进行随机重排,相当于"洗牌" *** 第13回:zip函数轻松合并列表,range对象竟然无视内存 **** str.join(列表) 以字符串str为分隔符,将列表中所有元素拼合为一个字符串, '-'.join(['a', 'b', 'c'])得到的结果 a-b-c #+begin_src python :results output from random import sample last_name = ["赵", "钱", "孙", "李", "周"] first_name = ["云", "学", "森", "权", "白", "公"] name = ''.join(sample(last_name, 1)+sample(first_name, 1)) print(name) #+end_src #+RESULTS: : 赵公 #+begin_src python :results output # 随机抽取名长度 from random import sample, randint last_name = ["赵", "钱", "孙", "李", "周", "杨"] first_name = ["云", "学", "森", "权", "白", "公", "秉"] name = ''.join(sample(last_name, 1)+sample(first_name, randint(1, 2))) print(name) #+end_src #+RESULTS: : 杨秉学 **** zip(a, b, ...) 将列表对应位置合并成一个元组,在将所有元组返回 #+begin_src python :results output school = ["蜀", "MIT", "Stanford", "HIT", "清华大学", "PKU"] last_name = ["赵", "钱", "孙", "李", "周", "杨"] first_name = ["云", "学", "森", "权", "白", "公"] names = zip(last_name, first_name) full = zip(school, last_name, first_name) for i in names: print(i) print(''.join(i)) print(f"================================") for i in full: print(i) print("".join(i)) #+end_src #+RESULTS: #+begin_example ('赵', '云') 赵云 ('钱', '学') 钱学 ('孙', '森') 孙森 ('李', '权') 李权 ('周', '白') 周白 ('杨', '公') 杨公 ================================ ('蜀', '赵', '云') 蜀赵云 ('MIT', '钱', '学') MIT钱学 ('Stanford', '孙', '森') Stanford孙森 ('HIT', '李', '权') HIT李权 ('清华大学', '周', '白') 清华大学周白 ('PKU', '杨', '公') PKU杨公 #+end_example ***** 迭代器 迭代(iterate):按某种顺序逐个访问 #+begin_src python # 对x中所有元素逐个提取访问 for i in x: print(i) #+end_src 支持迭代的对象(iterable):允许for循环对内部元素进行逐个访问 可迭代对象不仅仅是 *容器* ,还包括 /range/ , /zip/ 等类型 *** 第14回:生成式长得帅跑得快,迭代器拿时间换空间 **** 列表生成式 #+begin_src python :results output # 不使用列表生成式 p_usd = [250, 175, 300, 247] p_rmb = [] for i in p_usd: p_rmb.append(i*7) print(p_rmb) print(f"=============================") # 使用列表生成式 ## 1.写好[] ## 2.改写for循环的内容 ## for 循环的内容放到前面, for循环表达式放到 内容后面 p_usd = [250, 175, 300, 247] p_rmb = [i*7 for i in p_usd] print(p_rmb) #+end_src #+RESULTS: : [1750, 1225, 2100, 1729] : ============================= : [1750, 1225, 2100, 1729] #+begin_src python :results file #https://emacs-china.org/t/topic/3376 # 计算正弦值 from math import sin from matplotlib import pyplot a = [1, 2, 3, 4, 5, 6, 7] b = [sin(i) for i in a] print(f"计算a={a}的正弦值{b}") pyplot.plot(a, b) pyplot.savefig("./第14回/fig_sin.png") return './第14回/fig_sin.png' #+end_src #+RESULTS: #+ATTR_HTML: :width 300px #+ATTR_ORG: :width 400 [[file:./第14回/fig_sin.png]] #+begin_src python :results file from math import sin from matplotlib import pyplot a = [i/10 for i in range(1, 100)] b = [sin(i) for i in a] pyplot.plot(a,b) pyplot.savefig("./第14回/fig_sin2.png") return './第14回/fig_sin2.png' #+end_src #+RESULTS: #+ATTR_ORG: :width 300px [[file:./第14回/fig_sin2.png]] 生成式创建列表远远快于循环方式 #+begin_src python :results output from time import time a = range(1, 1000) b = range(1, 1000) t1 = time() c = [x * y for x in a for y in b ] print(f"生成式创建列表耗时{time()-t1}秒") d = [] t2 = time() for x in a: for y in b: d.append(i*j) print(f"循环创建列表耗时{time()-t2}秒") #+end_src #+RESULTS: : 生成式创建列表耗时0.05607318878173828秒 : 循环创建列表耗时0.10820722579956055秒 **** 节省内存方案 优点:需要调用那个元素,就临时计算该元素,而且清理完毕,始终不浪费内存空间 缺点:浪费CPU计算时间 ***** 1.生成规则 () 如果python 写的是[]是“列表生成式”,但是使用 () 就是“生成列表规则”,在内存中存储规则,只有在使用的时候才会进行计算 计算过程:在调用的时候,先计算出第1个元素,然后在计算第2个,以此类推; 同时尽快将第一个元素地址从内存中清除,以便节省空间 #+begin_src python :results output # 以下代码不要执行,会占满内存 a = range(1, 100000) b = range(1, 100000) c = [ x*y for x in a for y in b] for i in c: print(i) #+end_src #+RESULTS: : MemoryError #+begin_src python :results output # 延时计算 from time import time a = range(1, 100000) b = range(1, 100000) c = ( x*y for x in a for y in b) for i in c: print(i) #+end_src ***** 2.range类型 range与List区别:range 是在需要的时候才计算 ***** 3.zip类型 ***** 调用方法 range允许使用下标调用,zip和() 不能使用下标 #+begin_src python >>> a = range(10) >>> a[3] 3 >>> >>> x = [1,2,3] >>> y = [5,2,6] >>> z = zip(x,y) >>> z[3] Traceback (most recent call last): File "", line 1, in TypeError: 'zip' object is not subscriptable >>> >>> s = (i for i in x) >>> s[3] Traceback (most recent call last): File "", line 1, in TypeError: 'generator' object is not subscriptable #+end_src ****** 迭代器 在python中允许使用next()函数的对象就是迭代器(Iterator),迭代器中的元素一旦被读取,就无法重新读取 next()函数可以逐个访问 *zip* 或 *生成规则* 中的元素 next回一直访问,直到全部读完抛出异常 #+begin_src python :results output # 生成规则的使用 a = [1, 2, 3] x = ( i*i for i in a ) for i in range(3): print(next(x)) #+end_src #+RESULTS: : 1 : 4 : 9 #+begin_src python :results output a = [1, 2, 3] b = [2, 5, 7] x = zip( a, b) for i in range(3): print(next(x)) #+end_src #+RESULTS: : (1, 2) : (2, 5) : (3, 7) ******* 迭代器类型 ******** 普通迭代器(Iterator) 通过编写一个特殊类实现的 eg:zip ******** 生成器(Generator) 通过 *yield* 关键字 或 *()* 生成 ******* 可迭代对象(以时间换空间) 1.常见容器 2.range对象 3.迭代器 4.其他迭代对象 *** 第15回:字典也有生成式,却拿空间换时间 **** 列表与字典转换 ***** 完美二维列表 x=dict(列表) #+begin_src python :results output a = [ ["小明", 120], ["小红", 114], ["小刚", 92], ["YBX", 148], ["小方", 87] ] print(a) x = dict(a) print(x) #+end_src #+RESULTS: : [['小明', 120], ['小红', 114], ['小刚', 92], ['YBX', 148], ['小方', 87]] : {'小明': 120, '小红': 114, '小刚': 92, 'YBX': 148, '小方': 87} ***** 两个等长的列表 x=dict(zip(列表1, 列表2)) #+begin_src python :results output a = ["小明", "小红", "YBX", "小刚", "小方"] b = [120, 124, 149, 23, 98] d = dict(zip(a, b)) print(d) #+end_src #+RESULTS: : {'小明': 120, '小红': 124, 'YBX': 149, '小刚': 23, '小方': 98} ***** {}.fromkeys(列表, 默认值) #+begin_src python :results output a = ["小明", "小红", "YBX", "小刚", "小方"] f = {}.fromkeys(a) print(f) g = {}.fromkeys(a, 120) print(g) #+end_src #+RESULTS: : {'小明': None, '小红': None, 'YBX': None, '小刚': None, '小方': None} : {'小明': 120, '小红': 120, 'YBX': 120, '小刚': 120, '小方': 120} **** 字典生成式 用 for 循环书写 #+begin_src python :results output a = [ ['A', 20191122.0, 78.61, 79.19, 78.23, 79.12, 1869700], ['AA', 20191122.0, 20.39, 20.945, 20.39, 20.56, 44254000], ['BA', 20191122.0, 368.27, 373.55, 366.61, 371.34, 39157000], ['BABA', 20191122.0, 185.8, 186.78, 183.935, 186.78, 10541000], ['BAC', 20191122.0, 32.96, 33.32, 32.94, 33.18, 3878300] ] d = {} for x in a: d[ x[0] ] = x[5] print(d) #+end_src #+RESULTS: : {'A': 79.12, 'AA': 20.56, 'BA': 371.34, 'BABA': 186.78, 'BAC': 33.18} 用 字典生成式 书写 #+begin_src python :results output a = [ ['A', 20191122.0, 78.61, 79.19, 78.23, 79.12, 1869700], ['AA', 20191122.0, 20.39, 20.945, 20.39, 20.56, 44254000], ['BA', 20191122.0, 368.27, 373.55, 366.61, 371.34, 39157000], ['BABA', 20191122.0, 185.8, 186.78, 183.935, 186.78, 10541000], ['BAC', 20191122.0, 32.96, 33.32, 32.94, 33.18, 3878300] ] d = { x[0]:x[5] for x in a} # 因为生成的是字典,所以使用{} print(d) #+end_src #+RESULTS: `: {'A': 79.12, 'AA': 20.56, 'BA': 371.34, 'BABA': 186.78, 'BAC': 33.18} *** 第16回:​字典元素任遍历,元组赋值巧解包 **** 怎样遍历字典的键和值 #+begin_src python :results output d = {"张三": 5, "李四":2, "王五":3, "赵六": 0} print(f"==============遍历键===============") for i in d: print(i) print(f"==============遍历值===============") for i in d.values(): print(i) #+end_src #+RESULTS: #+begin_example ==============遍历键=============== 张三 李四 王五 赵六 ==============遍历值=============== 5 2 3 0 #+end_example **** items() 返回 *dictview* ,每个元素都是一个元组 #+begin_src python :results output d = {'A':2, 'B':4, 'C':4, 'E':1} for x, y in d.items(): print(x, y) #+end_src #+RESULTS: : A 2 : B 4 : C 4 : E 1 #+begin_src python :results output # 对调键值对 d = {"张三": "03", "李四":"98", "YBX":"120"} d2 = { y:x for x,y in d.items()} print(f"d的值是{d}") print(f"d2的值是{d2}") #+end_src #+RESULTS: : d的值是{'张三': '03', '李四': '98', 'YBX': '120'} : d2的值是{'03': '张三', '98': '李四', '120': 'YBX'} **** 解包 解包其实就是"去括号",将括号的中的变量分别赋值给变量 #+begin_src python :results output print(f"=============解包元组==============") a, b = ( 1, 2) print(a) print(b) print(f"=============解包列表==============") a, b = ["小明", "小红"] print(a) print(b) print(f"=============解包字典==============") # 只有键没有值 a, b = {"小红":1, "小明":2} print(a) print(b) print(f"=============解包集合==============") a, b = {"YBX", "小明"} print(a) print(b) print(f"=============多元赋值==============") a, b, c, d = 1, 2, 3, 4 print(f"a={a}, b={b}, c={c}, d={d}") print(f"=============字符串解包=============") a, b, c = "一二三" print(f"a={a}, b={b}, c={c}") #+end_src #+RESULTS: #+begin_example =============解包元组============== 1 2 =============解包列表============== 小明 小红 =============解包字典============== 小红 小明 =============解包集合============== 小明 YBX =============多元赋值============== a=1, b=2, c=3, d=4 =============字符串解包============= a=一, b=二, c=三 #+end_example #+begin_src python :results output # 通过解包实现交换变量 a, b = 3, 5 print(f"a={a}, b={b}") b, a = a, b #交换变量 print(f"a={a}, b={b}") #+end_src #+RESULTS: : a=3, b=5 : a=5, b=3 *** 第17回:合运算统计名单变动,Counter与chain简化数据分析 **** 集合的重要特性 1.*不* 允许出现重复元素 2.元素排列 *无* 特定顺序 3.*只能* 包含 *不可变* 类型 **** 创建集合 #+begin_src python :results output a = [ 23, 5, 7 ] x = set( a ) print(f"x的值是{x}") a = ( 1, 3, 4) x = set( a ) print(f"x的值是{x}") a = {'a':1, 'b':2, 'c':3} # 只有键没有值 x = set( a ) print(f"x的值是{x}") #+end_src #+RESULTS: : x的值是{7, 5, 23} : x的值是{1, 3, 4} : x的值是{'b', 'c', 'a'} **** set类型与集合运算 #+begin_src python :results output a = {'A', 'B', 'C', 'D'} b = {'B', 'E', 'D', 'F'} c = a & b # 计算交集 d = a &{'Z'} print(f"交集运算:{c}") print(f"空集:{d}") #因为字典也是{},所以为了防止混淆就是 set() 不用{}了 e = a | b print(f"并集运算:{e}") f = a - b print(f"差集运算a里有b里没有:{f}") #+end_src #+RESULTS: : 交集运算:{'B', 'D'} : 空集:set() : 并集运算:{'C', 'B', 'D', 'E', 'F', 'A'} : 差集运算a里有b里没有:{'A', 'C'} **** collections.Counter计数器生成字典 #+begin_src python :results output from collections import Counter a = ["张三", "李四", "张三", "YBX", "aaa", "YBX", "YBX"] c = Counter(a) print(c) #+end_src #+RESULTS: : Counter({'YBX': 3, '张三': 2, '李四': 1, 'aaa': 1}) #+begin_src python :results output from collections import Counter day1 = ["YBX", "THU", "PKU", "THU", "JLU", "YBX"] day2 = ["THU", "PKU", "YBX", "MIT"] c1 = Counter(day1) c2 = Counter(day2) # 进行集合的加法 c = c1+c2 print(c) d = c1-c2 print(d) # Counter减法只保留整数结果,其他结果一律抛弃 #+end_src #+RESULTS: : Counter({'YBX': 3, 'THU': 3, 'PKU': 2, 'JLU': 1, 'MIT': 1}) : Counter({'YBX': 1, 'THU': 1, 'JLU': 1}) **** iter iterable略写,就是操作可迭代对象 ***** 二维列表转换成一维列表 #+begin_src python :results output from itertools import chain a = [[1, 5], [3, 4], [2, 1, 3]] x = list(chain( *a )) print(a) #+end_src #+RESULTS: : [1, 5, 3, 4, 2, 1, 3] *** 第18回:拷贝容器细分深与浅,可变对象难做默认值 **** 容器坑 ***** 使用 *可变* 类型对象 ***** 深拷贝/浅拷贝 #+begin_src python :results output # 浅拷贝 a = ['A', 'B', 'C'] b = a print(f"a={a}, b={b}") b[0] = "甲" print(f"a={a}, b={b}") # 浅拷贝(假深拷贝) ## 以下内容看似深拷贝 a = ['A', 'B', 'C'] b = a.copy() print(f"a={a}, b={b}") b[0] = "甲" print(f"a={a}, b={b}") ## 揭穿.copy() a = ['A', ['B', 'C'], 'D'] b = a.copy() print(f"a={a}, b={b}") b[1][0] = "乙" print(f"a={a}, b={b}") # 深拷贝 deepcopy() a = ['A', ['B', 'C'], 'D'] import copy b = copy.deepcopy(a) print(f"a={a}, b={b}") b[1][0] = "乙" print(f"a={a}, b={b}") #+end_src #+RESULTS: : a=['A', 'B', 'C'], b=['A', 'B', 'C'] : a=['甲', 'B', 'C'], b=['甲', 'B', 'C'] : a=['A', 'B', 'C'], b=['A', 'B', 'C'] : a=['A', 'B', 'C'], b=['甲', 'B', 'C'] : a=['A', ['B', 'C'], 'D'], b=['A', ['B', 'C'], 'D'] : a=['A', ['乙', 'C'], 'D'], b=['A', ['乙', 'C'], 'D'] : a=['A', ['B', 'C'], 'D'], b=['A', ['B', 'C'], 'D'] : a=['A', ['B', 'C'], 'D'], b=['A', ['乙', 'C'], 'D'] ***** 误用 *乘法* 制作 二维列表 #+begin_src python :results output a = [1, 2, 3] b = a * 3 # 将方括号里面的内容重复3次 print(b) #+end_src #+RESULTS: : [1, 2, 3, 1, 2, 3, 1, 2, 3] #+begin_src python :results output # 创建二维列表 b = [ [0, 0, 0] for i in range(2)] # 列表生成式生成2维列表 print(f"b = {b}") ## 简化版 b = [ [0]*3 for _ in range(2)] # 这里的 _ 表示只循环2遍但是没有什么实际用途 print(f"b = {b}") #+end_src #+RESULTS: : b = [[0, 0, 0], [0, 0, 0]] : b = [[0, 0, 0], [0, 0, 0]] *** 第19回:Numpy玩转二维结构,Pandas搞定统计分析 **** NumPy(Numeric Python) 用于科学计算 ***** ndarray(N-dimensional array) ******* 矩阵转换 #+begin_src python :results output x = [15, 20, 16, 8, 90, 21, 23, 985, 213] y = (12, 43, 211, 665, 7665, 90, 323, 89, 21) import numpy as np # 使用array()将列表等容器转换为 ndarray 类型的数组 ## ndarray 数据看作矩阵可以进行 整体的数学运算 a = np.array(x) b = np.array(y) c = a*3 d = b*3 print(f"a={a}, c={c}") print(f"b={b}, d={d}") e = np.array( range(9) ) f = a - e print(f"矩阵减法\n a={a}\n e={e}\n f=a-e={f}") # 使用 tolist() 将 ndarray 转换为 List 对象 g = f.tolist() print(f" ndarray类型:f = {f} \n list类型: g = {g} ") #+end_src #+RESULTS: : a=[ 15 20 16 8 90 21 23 985 213], c=[ 45 60 48 24 270 63 69 2955 639] : b=[ 12 43 211 665 7665 90 323 89 21], d=[ 36 129 633 1995 22995 270 969 267 63] : 矩阵减法 : a=[ 15 20 16 8 90 21 23 985 213] : e=[0 1 2 3 4 5 6 7 8] : f=a-e=[ 15 19 14 5 86 16 17 978 205] : ndarray类型:f = [ 15 19 14 5 86 16 17 978 205] : list类型: g = [15, 19, 14, 5, 86, 16, 17, 978, 205] #+begin_src python :results output # 实际应用 各月收入 = [3000, 2500, 2800, 4400] 各月支出 = [2700, 3200, 2100, 4300] import numpy as np a = np.array(各月收入) b = np.array(各月支出) 各月余额 = a - b print(f"各月余额={各月余额}") #+end_src #+RESULTS: : 各月余额=[ 300 -700 700 100] ******* 矩阵数学公式 #+begin_src python :results output # 使用 numpy 模块 提供的各种函数对数组进行统计运算 x = [15, 20, 16, 8, 90, 21, 23, 985, 213] import numpy as np a = np.array(x) b = np.log(a) #可以使用numpy模块提供的各种数学公式进行统计运算 print(f"a = {a}\n b = {b}") #+end_src #+RESULTS: : a = [ 15 20 16 8 90 21 23 985 213] : b = [2.7080502 2.99573227 2.77258872 2.07944154 4.49980967 3.04452244 : 3.13549422 6.89264164 5.36129217] ******* 矩阵变形 #+begin_src python :results output # 使用 reshape 将一维列表转换为二维结构的 ndarray x = [15, 20, 16, 8, 90, 21, 23, 985, 213, 932, 892, 10] import numpy as np a = np.array( x ) b = a.reshape(3, 4) c = a.reshape(2, 6) print(f"a = {a}\n b = {b}\n c = {c}") #+end_src #+RESULTS: : a = [ 15 20 16 8 90 21 23 985 213 932 892 10] : b = [[ 15 20 16 8] : [ 90 21 23 985] : [213 932 892 10]] : c = [[ 15 20 16 8 90 21] : [ 23 985 213 932 892 10]] ******* 矩阵转置 #+begin_src python :results output x = [15, 20, 16, 8, 90, 21, 23, 985, 213, 932, 892, 10] import numpy as np a = np.array( x ) b = a.reshape(2, 6) c = b.T print(f"a = {a}\n b = {b}\n c = {c}") #+end_src #+RESULTS: : a = [ 15 20 16 8 90 21 23 985 213 932 892 10] : b = [[ 15 20 16 8 90 21] : [ 23 985 213 932 892 10]] : c = [[ 15 23] : [ 20 985] : [ 16 213] : [ 8 932] : [ 90 892] : [ 21 10]] **** Pandas(Panel Data) 用于数据分析(主要是统计学) Pandas是基于Numpy开发的 ***** Pandas 中数据类型 只有一维 series 多行多列 dataframe ** 第三卷 字符串与正则表达式 *** 第20回:字符文本必须编成数字,回车换行都要转义表达 **** 实现字符与数字的转换 #+begin_src python :results output # ord(x)返回 字符x 的ASCII编码 print(f"The ASCII of A = {ord('A')}") print(f"The ASCII of 1 = {ord('1')}") # chr(num)返回 数字num 对应的字符x print(f"The char of the num 64 = {chr(64)}") print(f"The char of the num 90 = {chr(90)}") #+end_src #+RESULTS: : The ASCII of A = 65 : The ASCII of 1 = 49 : The char of the num 64 = @ : The char of the num 90 = Z #+begin_src python :results output s1 = "白日依山尽"+chr(10) + "黄河入海流" +chr(10) + "欲穷千里目" + chr(10) + "更上一层楼" + chr(10) print(s1) #+end_src #+RESULTS: : 白日依山尽 : 黄河入海流 : 欲穷千里目 : 更上一层楼 : #+begin_src python :results output # 转义字符 s1 = "白日依山尽\n黄河入海流\n欲穷千里目\n更上一层楼\n" print(s1) #+end_src #+RESULTS: : 白日依山尽 : 黄河入海流 : 欲穷千里目 : 更上一层楼 : *** 第23回:正则表达式推演千言万语,量词元字符匹配各种文章 **** 正则表达式(Regular Express) ***** 练习正则表达式 右侧链接[[https://regex101.com/][regex101.com]]可以练习 需要导入 re 模块 ***** 正则表达式语法 | 符号 | 内容 | |---------------+--------------------------------------------------------------------| | \d | 一个数字字符 | | \D | \d的反义词;相当于[^0-9]一个非数字字符 | | \s | 一个空白字符, eg:空格、换行、缩进 | | \S | \s的反义词 | | \w | 一个文字字符, eg:字母和数字,不包括标点,空格(在Python3可代表汉字) | | \b | 代表*文字字符*与*非文字字符*之间的位置 | | | | | . | 代表任意一个字符 | | {数字} | 量词 | | {num1, num2} | 至少出现num1次,最多出现num2次 | | {num1, } | 至少出现num1次 | | | | | a+ | 相当于a{1, },连续 a 1次或以上 | | a? | 相当于a{0,1},代表a不出现或者出现1次 | | a* | 相当于a{0, },代表a 0次或以上 | | | | | [abc] | 找一个字符,他或者是a,或者是b,或者是c | | [0123456789]+ | 就是\d+ | | [0-9] | 等价\d | | [3-7] | 等价[34567] | | [0-9a-z] | 查找以数字或字母的一个字符 | | [^abc] | 反义:除了abc以外的任何字符 | | | | | () | 捕获组 | | ? | 懒惰搜索:在量词(*+?{})后面加上?当有多种选项时,就会选择最短者 | | | | | ^ | 代表行首位置 | | $ | 代表行尾位置 | | | | 注意; 1.如果想在字符组中表示 - , 应当将其放在第一或最后一位,否则会认定是范围标记 eg:[-;>?,"] 2.在[]中的的字符组.*+?{}()等符号都代表普通字符,没有“量词”等特殊含义 3.[^abc]:*一个*不是a/b/c的任意字符 [a^bc]/[ab^c][abc^]:一个字符a/b/c/^ #+begin_src python :results output s = "010-63029870 松汇东路1-3号 邮编:201600" import re a = re.findall('\d', s) # 查询单个数字 print(f"s中的数字={a}") b = re.findall('0\d', s) print(f"s中0开头的数字={b}") # 量词的使用 {} c = re.findall('\d{6}', s) print(f"s中连续6位的数字={c}") # 正则表达式不能重叠 s = "123456789" d = re.findall('\d{3}', s) print(f"s中连续3个数字{d}, 这里面没有234, 345等重叠的内容") s = "010 - 63029870 松汇东路1-3号 邮编:201600" d = re.findall('\d+ - \d+', s) # 匹配电话号码 因为有 - (前后是空格) print(f"s中的点号号码{d}") s = "010 - 63029870 松汇东路13号 邮编:201600,联系人:张三, 电话: 0431-13888889999" d = re.findall('\d+ ?- ?\d+', s) # 这里的 ?(?前有空格)表示空格可有可无 print(f"s中全部的电话号码{d}") #+end_src #+RESULTS: : s中的数字=['0', '1', '0', '6', '3', '0', '2', '9', '8', '7', '0', '1', '3', '2', '0', '1', '6', '0', '0'] : s中0开头的数字=['01', '02', '01', '00'] : s中连续6位的数字=['630298', '201600'] : s中连续3个数字['123', '456', '789'], 这里面没有234, 345等重叠的内容 : s中的点号号码['010 - 63029870'] : s中全部的电话号码['010 - 63029870', '0431-13888889999'] #+begin_src python :results output s = """A公司,发货5000台,联系人: 张三,电话 010 - 88223343,邮箱zs@a.com B公司:联系人:李四,电话: 0418-5566778,邮箱: lisi@b.com C公司发货200台,联系人: 王五,电话是 (024) 66667777,邮箱: wangwu@c.com。 D公司电话联系,联系人: 赵六,电话0520-33227788,邮箱是 zhaoliu@d.com. E公司联系人:田七,电话 01083232563,邮箱 tiangie.com F公司,联系人: John Willams ,电话 (001) 33243334,邮箱 johnw@f.com G公司,联系人: Ken Wang,电话 (001) 56523333,邮箱 kenwang@g.com""" import re a = re.findall("电话[是\s:(]*(\d+)[-)\s]*(\d+)", s) print(a) for 区号, 本地号 in a: print(区号, 本地号) print(f"{区号}-{本地号}") #+end_src #+RESULTS: #+begin_example [('010', '88223343'), ('024', '66667777'), ('0520', '33227788'), ('0108323256', '3'), ('001', '33243334'), ('001', '56523333')] 010 88223343 010-88223343 024 66667777 024-66667777 0520 33227788 0520-33227788 0108323256 3 0108323256-3 001 33243334 001-33243334 001 56523333 001-56523333 #+end_example #+begin_src python :results output s = """一​年级小学生必读书目 1、《中国古代寓言故事》管钟编写北京人民文学出版社2、《中外神话传说》田新利选编北京人民文学出版社3、《十万个为什么》卢嘉锡主编少年儿童出版社4、《与乌儿一起飞翔》郑作新着湖南少儿出版社5、《海底两万里》(法)儒勒.凡尔纳北京教育出版社 6、《汉字的故事》梅子涵着上海科普出版社 7、《安徒生童话选集》(丹麦)安徒生 二年级小学生必读书目 1、《克雷洛徒生着,叶君健译译林出版社夫寓言全集》(俄)克雷洛夫着,裴家勤译译林出版社 2、《拉.封丹寓言》(法)拉。封丹着倪海曙译上海译文出版社 3、《格林童话全集》(德)雅各布.格林威廉.格林着译林出版社4、《科学王国里的故事》王会等主编河北少年儿童出版社 5、《神奇的符号》苏步清着湖南少儿出版社 6、《诗词中的科学》唐鲁峰等江苏人民出版社 7、《中国古代科幻故事集》杨鹏、刘道远中国少年儿童出版社 8、《阿凡提的故事》赵世杰编译中国少年儿童出版社 9、《三毛流浪记》张乐平少年儿童出版社 10、《宝葫芦的秘密》张天翼农村读物出版社 11、《今年你七岁》刘健屏中国少年儿童出版社 12、《荒漠奇踪》严阵中国少年儿童出版社 """ import re a1 = re.findall("《.*》", s) print(a1) # 重新优化正则表达式 print("===============================================") a2 = re.findall("《[^》]*》", s) print(a2) # 懒惰搜索 print("===============================================") a3 = re.findall("《.*?》", s) print(a3) # 寻找北京出版社的书籍 print("===============================================") a4 = re.findall("《[^》]+》[^》]*北京\w*", s) print(a4) #+begin_src python :results output #+RESULTS: : ['《中国古代寓言故事》管钟编写北京人民文学出版社2、《中外神话传说》田新利选编北京人民文学出版社3、《十万个为什么》卢嘉锡主编少年儿童出版社4、《与乌儿一起飞翔》郑作新着湖南少儿出版社5、《海底两万里》(法)儒勒.凡尔纳北京教育出版社 6、《汉字的故事》梅子涵着上海科普出版社 7、《安徒生童话选集》', '《克雷洛徒生着,叶君健译译林出版社夫寓言全集》(俄)克雷洛夫着,裴家勤译译林出版社 2、《拉.封丹寓言》(法)拉。封丹着倪海曙译上海译文出版社 3、《格林童话全集》(德)雅各布.格林威廉.格林着译林出版社4、《科学王国里的故事》王会等主编河北少年儿童出版社 5、《神奇的符号》苏步清着湖南少儿出版社 6、《诗词中的科学》唐鲁峰等江苏人民出版社 7、《中国古代科幻故事集》杨鹏、刘道远中国少年儿童出版社 8、《阿凡提的故事》赵世杰编译中国少年儿童出版社 9、《三毛流浪记》张乐平少年儿童出版社 10、《宝葫芦的秘密》张天翼农村读物出版社 11、《今年你七岁》刘健屏中国少年儿童出版社 12、《荒漠奇踪》'] : =============================================== : ['《中国古代寓言故事》', '《中外神话传说》', '《十万个为什么》', '《与乌儿一起飞翔》', '《海底两万里》', '《汉字的故事》', '《安徒生童话选集》', '《克雷洛徒生着,叶君健译译林出版社夫寓言全集》', '《拉.封丹寓言》', '《格林童话全集》', '《科学王国里的故事》', '《神奇的符号》', '《诗词中的科学》', '《中国古代科幻故事集》', '《阿凡提的故事》', '《三毛流浪记》', '《宝葫芦的秘密》', '《今年你七岁》', '《荒漠奇踪》'] : =============================================== : ['《中国古代寓言故事》', '《中外神话传说》', '《十万个为什么》', '《与乌儿一起飞翔》', '《海底两万里》', '《汉字的故事》', '《安徒生童话选集》', '《克雷洛徒生着,叶君健译译林出版社夫寓言全集》', '《拉.封丹寓言》', '《格林童话全集》', '《科学王国里的故事》', '《神奇的符号》', '《诗词中的科学》', '《中国古代科幻故事集》', '《阿凡提的故事》', '《三毛流浪记》', '《宝葫芦的秘密》', '《今年你七岁》', '《荒漠奇踪》'] : =============================================== : ['《中国古代寓言故事》管钟编写北京人民文学出版社2', '《中外神话传说》田新利选编北京人民文学出版社3', '《海底两万里》(法)儒勒.凡尔纳北京教育出版社'] *** 第26回 加问号实现懒惰搜索,捕获组抽取局部信息 捕获组:就是将正则表达式中某一部分括起来,该部分内容就会被作为一个捕获结果单独返回 分类情况: 1.如果正则表达式中*只*含有一个捕获组,则结果列表中每一项都是一个字符串,即捕获组的内容 2.如果正则表达式中含有多个捕获组,则结果列表中每一项都是一个元组,其中包含各个捕获组内容 #+begin_src python :results output s = """​ A公司,发货5000台,联系人:张三,电话010-88223343,邮箱zs@a.com B公司:联系人:李四,电话:0418-5566778,邮箱:lisi@b.com C公司发货200台,联系人:王五,电话是(024)66667777,邮箱:wangwu@c.com D公司电话联系,联系人:赵六,电话0520-33227788,邮箱是是zhaoliu@d.com E公司联系人:田七,电话01083232563,邮箱 tianqi@e.com F公司,联系人:JohnWillams,电话(001)33243334,邮箱 johnw@f.com G公司,联系人:KenWang,电话(001)56523333,邮箱 kkenwang@g.com""" # 使用连续的3个”“”,可以直接定义多行字符串 # 但是一般注释也是这样 import re a = re.findall("电话[是\s:(]*(\d+)[-)\s]*(\d+)", s) print(a) for 区号, 本地号 in a: print(f"{区号}-{本地号}") #+end_src #+RESULTS: : [('010', '88223343'), ('0418', '5566778'), ('024', '66667777'), ('0520', '33227788'), ('0108323256', '3'), ('001', '33243334'), ('001', '56523333')] : 010-88223343 : 0418-5566778 : 024-66667777 : 0520-33227788 : 0108323256-3 : 001-33243334 : 001-56523333 *** 第27回反斜线上转义来,今日方知我是我 #+begin_src python :results output # 寻找全部外文图书 s = """一​年级小学生必读书目 1、《中国古代寓言故事》管钟编写北京人民文学出版社2、《中外神话传说》田新利选编北京人民文学出版社3、《十万个为什么》卢嘉锡主编少年儿童出版社4、《与乌儿一起飞翔》郑作新着湖南少儿出版社5、《海底两万里》(法)儒勒.凡尔纳北京教育出版社 6、《汉字的故事》梅子涵着上海科普出版社 7、《安徒生童话选集》(丹麦)安徒生 二年级小学生必读书目 1、《克雷洛徒生着,叶君健译译林出版社夫寓言全集》(俄)克雷洛夫着,裴家勤译译林出版社 2、《拉.封丹寓言》(法)拉。封丹着倪海曙译上海译文出版社 3、《格林童话全集》(德)雅各布.格林威廉.格林着译林出版社4、《科学王国里的故事》王会等主编河北少年儿童出版社 5、《神奇的符号》苏步清着湖南少儿出版社 6、《诗词中的科学》唐鲁峰等江苏人民出版社 7、《中国古代科幻故事集》杨鹏、刘道远中国少年儿童出版社 8、《阿凡提的故事》赵世杰编译中国少年儿童出版社 9、《三毛流浪记》张乐平少年儿童出版社 10、《宝葫芦的秘密》张天翼农村读物出版社 11、《今年你七岁》刘健屏中国少年儿童出版社 12、《荒漠奇踪》严阵中国少年儿童出版社 """ import re National = re.findall("《[^》]+》\((.*?)\)", s) print(National) #+end_src #+RESULTS: : ['法', '丹麦', '俄', '法', '德'] **** r字符串 在字符串*前*加上/r/之后,字符串中的大部分"反斜线\"都自动失去转义功能,只作为普通的反斜线字符 #+begin_src python :results output print("\b\w+\b") print(r"\b\w+\b") #+end_src *** 第28回括号分组有“复”同享,多行模式首尾分明 重复出现的情况 #+begin_src python :results output # ()分组 s = """ ABCBDABCABCCCCCCCABCCHJSABBBCBACDBBBBABCBDACBBCBCABCABCABCCCDABCDABDEBDEB """ import re # a = re.findall("(ABC)+", s) #捕获组的形式 # (?:)表示非捕获组,仅用于分组、不会被视为捕获组,也不会得到任何捕获结果 a = re.findall("(?:ABC)+", s) #abc重复多次出现-分组 print(a) #+end_src #+RESULTS: : ['ABC', 'ABCABC', 'ABC', 'ABC', 'ABCABCABC', 'ABC'] *** 第29回单行模式只管小数点,网抓图片仍是字节流 *** 第30回环视上下文精确定位,正则配循环所向无敌 *** 第31回有Word之替换,无案牍之劳形 *** 第32回反向引用代表重复,Python正则功能良多 ** 第四卷 面向对象原理与语法 *** [[https://mp.weixin.qq.com/s/_WWbsErnNZ-SDjSQBO0cZQ][第34回 构造方法统一属性定义,封装对象不惧万马奔腾]] **** 构造方法 命名:__init__ 调用:在创建对象时,由Python自动调用。 #+begin_src python :results output class MiShu: def __init__(self): self.name = '111' def say_hello(self): print(f"Hello Leader, I am {self.name}") if "__main__" == __name__: m1 = MiShu() m2 = MiShu() m1.name = 'ZhangSan' m2.name = 'LiSi' m1.say_hello() m2.say_hello() #+end_src #+RESULTS: : Hello Leader, I am ZhangSan : Hello Leader, I am LiSi #+begin_src python :results output class MiShu: def __init__(self, n, a, i): self.name = n self.age = a self.id = i def say_hello(self): print(f"Hello Leader, I am {self.name}, age is {self.age}, job number is {self.id}") if "__main__" == __name__: m1 = MiShu("Zhangsan", 29, "A013") m2 = MiShu("LiSi", 31, "A015") m1.say_hello() m2.say_hello() #+end_src #+RESULTS: : Hello Leader, I am Zhangsan, age is 29, job number is A013 : Hello Leader, I am LiSi, age is 31, job number is A015 **** 封装 #+begin_src python :results output # 面向过程 import random import time name_1 = "Test1" speed_1 = 5 loc_1 = 0 i =0 while i<5: # while True: loc_1 += round(speed_1 * random.random()) #因为random()返回0到1之间的随机小数,所以每次循环增加的距离都不同。如果随机数返回0则不增加;如果返回0.5则增加2.5米,如果返回1则增加5米。 print(f"{name_1} has run {loc_1} minters!") time.sleep(0.5) i = i+1 # can delete #+end_src #+RESULTS: : Test1 has run 1 minters! : Test1 has run 4 minters! : Test1 has run 5 minters! : Test1 has run 6 minters! : Test1 has run 10 minters! #+begin_src python :results output import random import time class Horse: def __init__(self, n, s): self.name = n self.speed = s self.loc = 0 def run(self): self.loc += round(self.speed * random.random()) print(f"{self.name} has run {self.loc} minters!") if "__main__" == __name__: h1 = Horse("Test1", 5) h2 = Horse("Test2", 6) h3 = Horse("Test3", 9) i = 0 while i<5: h1.run() h2.run() h3.run() time.sleep(0.5) i+=1 #+end_src #+RESULTS: #+begin_example Test1 has run 4 minters! Test2 has run 3 minters! Test3 has run 2 minters! Test1 has run 9 minters! Test2 has run 6 minters! Test3 has run 7 minters! Test1 has run 11 minters! Test2 has run 7 minters! Test3 has run 9 minters! Test1 has run 14 minters! Test2 has run 11 minters! Test3 has run 12 minters! Test1 has run 18 minters! Test2 has run 11 minters! Test3 has run 19 minters! #+end_example *** [[https://mp.weixin.qq.com/s/II8nSbNp-R4W7xODwPhv2g][第35回面向对象便于分工协作,成员私有避免乱写乱读]] **** 私有成员__: 如果一个属性或方法的名字是以两个下划线__开始,它就是一个私有属性或私有方法。 私有成员只能在class类定义代码中使用,也就是只能被这个类自己的方法调用,而class之外的代码不能直接调用它。 #+begin_src python :results output # python中的私有不是完全的私有不是不能完全修改 class Horse: def __init__(self): self.__loc = 0 def print_loc(self): print(f"当前位置:{self.__loc}") h1 = Horse() h1.print_loc() h1._Horse__loc = 999 h1.print_loc() #也修改了所谓的不能修改的室友变量 #+end_src #+RESULTS: : 当前位置:0 : 当前位置:999 *** [[][第36回pygame支持2D游戏,做动画只需边写边擦]] *** [[][第37回方法多态打破种类隔离,只看功能不分你我高低]] *** [[]第38回继承父类得到创业资本,覆盖方法走出自我新篇]] *** [[]第39回多继承自动获得多方法,父属性并未传给子类别]] *** [[][第40回指定对象作为参数,相互调用实现协同]] ** 第五卷 理解函数与函数式编程 *** [[][第41回寻常只道Python好,不识对象是真身]] *** [[][第42回写函数写数字本质相似,赋变量做参数样样都行]] *** [[][第43回单行代码处理全部列表,一个map可抵一套循环]] *** [[][第44回lambda表达式短小精悍,可匿名可传参灵活自如]] *** [[][第45回reduce席卷容器,利滚利通吃全局]] *** [[][第46回递归算法分身有术,搜遍全局路尽方出]] *** [[][第47回装饰器做改革精通世故,新人进旧人留和谐相处]] ** 结尾尾声 *** [[][第48回 提高篇结语:学问不可有遗力,编程功夫今始成]]