61 提取后缀名
>>> import os>>> os.path.splitext('D:/source/dataset/new_file.txt')('D:/source/dataset/new_file', '.txt') *#[1]:后缀名*
62 提取完整文件名
>>> import os>>> os.path.split('D:/source/dataset/new_file.txt')('D:/source/dataset', 'new_file.txt')
二、 Python 核心 12 例
63 斐波那契数列前n项
>>> def fibonacci(n):a, b = 1, 1for _ in range(n):yield aa, b = b, a+b *# 注意这种赋值*>>> for fib in fibonacci(10):print(fib)11235813213455
64 list 等分 n 组
>>> from math import ceil>>> def divide_iter(lst, n):if n <= 0:yield lstreturni, div = 0, ceil(len(lst) / n)while i < n:yield lst[i * div: (i + 1) * div]i += 1>>> for group in divide_iter([1,2,3,4,5],2):print(group)[1, 2, 3][4, 5]
65 yield 解释
有好几位同学问我,生成器到底该怎么理解 。
在这里我总结几句话,看看是否对不理解生成器的朋友有帮助 。
生成器首先是一个 “特殊的” return ,遇到 yield 立即中断返回 。
但是,又与 return 不同,yield 后下一次执行会进入到yield 的下一句代码,而不像 return 下一次执行还是从函数体的第一句开始执行 。
可能还是没说清,那就用图解释一下:
第一次 yield 返回 1
文章插图
第二次迭代,直接到位置 2 这句代码:
文章插图
然后再走 for ,再 yield ,重复下去,直到for结束 。
以上就是理解 yield 的重点一个方面 。
66 装饰器
66.1 定义装饰器
time 模块大家比较清楚,第一个导入 wraps 函数(装饰器)为确保被装饰的函数名称等属性不发生改变用的,这点现在不清楚也问题不大,实践一下就知道了 。
from functools import wrapsimport time
定义一个装饰器:print_info,装饰器函数入参要求为函数,返回值要求也为函数 。如下,入参为函数 f, 返回参数 info 也为函数,满足要求 。
def print_info(f):"""@para: f, 入参函数名称"""@wraps(f) # 确保函数f名称等属性不发生改变def info():print('正在调用函数名称为: %s ' % (f.__name__,))t1 = time.time()f()t2 = time.time()delta = (t2 - t1)print('%s 函数执行时长为:%f s' % (f.__name__,delta))return info
66.2使用装饰器使用 print_info 装饰器,分别修饰 f1, f2 函数 。
软件工程要求尽量一次定义,多次被复用 。
@print_infodef f1():time.sleep(1.0)@print_infodef f2():time.sleep(2.0)
66.3 使用装饰后的函数使用 f1, f2 函数:f1()f2()*# 输出信息如下:**# 正在调用函数名称为:f1**# f1 函数执行时长为:1.000000 s**# 正在调用函数名称为:f2**# f2 函数执行时长为:2.000000 s
67 迭代器案例一个类如何成为迭代器类型,请看官方PEP说明:
文章插图
即必须实现两个方法(或者叫两种协议):iter , _next_
下面编写一个迭代器类:
class YourRange():def __init__(self, start, end):self.value = https://www.isolves.com/it/cxkf/yy/Python/2020-06-11/startself.end = end*# 成为迭代器类型的关键协议*def __iter__(self):return self*# 当前迭代器状态(位置)的下一个位置*def __next__(self):if self.value >= self.end:raise StopIterationcur = self.valueself.value += 1return cur
使用这个迭代器:yr = YourRange(5, 12)for e in yr:print(e)
迭代器实现iter 协议,它就能在 for 上迭代,参考官网PEP解释:文章插图
文章最后提个问题,如果此时运行:
next(yr)
会输出 5,还是报错?
如果 yr 是 list,for 遍历后,再 next(iter(yr)) 又会输出什么?
如果能分清这些问题,恭喜你,已经真正理解迭代器迭代和容器遍历的区别 。如果你还拿不准,欢迎交流 。
下面使用 4 种常见的绘图库绘制柱状图和折线图,使用尽可能最少的代码绘制,快速入门这些库是本文的写作目的 。
68 matplotlib
导入包:
import matplotlibmatplotlib.__version__*# '2.2.2'*import matplotlib.pyplot as plt
绘图代码:import matplotlib.pyplot as pltplt.plot([0, 1, 2, 3, 4, 5],[1.5, 1, -1.3, 0.7, 0.8, 0.9],c='red')plt.bar([0, 1, 2, 3, 4, 5],[2, 0.5, 0.7, -1.2, 0.3, 0.4])plt.show()
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 用Python从头开始实现简单遗传算法
- Pyqtgraph是Python平台上一种功能强大的2D/3D绘图库
- 这个小众网站,竟包含有100种实用工具,还能手把手教你修电脑
- Python的10个神奇的技巧
- 程序员用Python实现自动化控制键盘和鼠标
- 退休|49岁投了1000份简历没有找到工作,怎样才能工作到65岁?
- Python语法之Django框架-安装
- 一篇文章搞定Python连接mysql数据库模块PyMySQL
- 一篇文章搞懂Python协程
- 十几行Python代码轻松实现txt转xls,方便快捷