想学会一门语言不是一朝一夕的事情,本文是按照业务数据分析师/商业分析师 的路线来讲 Python 的学习路径。若大家想成为技术型的分析师,或者未来往数 据挖掘发展,建议你要比文章内容学得更深,所有的代码最好都手打一遍,这是 最有效的学习方式。
https://www.liaoxuefeng.com/wiki/1016959663602400
https://www.runoob.com/python/python-tutorial.html
https://python3-cookbook.readthedocs.io/zh_CN/latest/chapters/p08_classes_and_objects.html
IDE集成开发环境(Integrated Development Environment )工具。用 Anaconda 足矣。Anaconda是专业的数据科学计算环境,包含180+的科学包及其依赖项的发行版本。其包含的科学包包括:conda, numpy, scipy, ipython notebook等。不需要多余的安装和调试。
Anaconda(官方网站)就是可以便捷获取包且对包能够进行管理,同时对环境可以统一管理的发行版本。Anaconda包含了conda、Python在内的超过180个科学包及其依赖项。
Mac 版本只有一个 Navigator 导航。数 据分析最常用的程序叫 Jupyter,以前被称为 IPython Notebook,是一个交互式的 笔记本,能快速创建程序,支持实时代码、可视化和 Markdown 语言。 点击 Jupyter 进入,它会自动创建一个本地环境 localhost。
Anaconda可以在以下系统平台中安装和使用:
① 图形界面安装
前往官方下载页面下载。有两个版本可供选择:Python 3.6 和 Python 2.7,我下载的是前者。选择版之后点击“64-Bit Graphical Installer”进行下载。
完成下载之后,双击下载文件,在对话框中“Introduction”、“Read Me”、“License”部分可直接点击下一步。
“Destination Select”部分选择“Install for me only”并点击下一步。
注意:若有错误提示信息“You cannot install Anaconda in this location”则重新选择“Install for me only”并点击下一步。
“Installation Type”部分,可以点击“Change Install Location”来改变安装位置。标准的安装路径是在用户的家目录下。在这一步我没有改变安装位置。若选择默认安装路径,则直接点击“Install”进行安装。
等待“Installation”部分结束,在“Summary”部分若看到“The installation was completed successfully.”则安装成功,直接点击“Close”关闭对话框。
在mac的Launchpad中可以找到名为“Anaconda-Navigator”的图标,点击打开。
若“Anaconda-Navigator”成功启动,则说明真正成功地安装了Anaconda;如果未成功,请务必仔细检查以上安装步骤。
“Anaconda-Navigator”中已经包含“Jupyter Notebook”、“Jupyterlab”、“Qtconsole”和“Spyder”。(图中的“Rstudio”是我后来安装的,但它默认出现在“Anaconda-Navigator”的启动界面,只需要点击“Install”便可安装。)
完成安装。
前往官方下载页面下载。有两个版本可供选择:Python 3.6 和 Python 2.7,我下载的是前者。选择版之后点击“64-Bit Command-Line Installer”进行下载。
完成下载之后,在mac的Launchpad中找到“其他”并打开“终端”。
注意:
安装过程中,看到提示“In order to continue the installation process, please review the license agreement.”(“请浏览许可证协议以便继续安装。”),点击“Enter”查看“许可证协议”。
在“许可证协议”界面将屏幕滚动至底,输入“yes”表示同意许可证协议内容。然后进行下一步。
安装过程中,提示“Press Enter to confirm the location, Press CTRL-C to cancel the installation or specify an alternate installation directory.”(“按回车键确认安装路径,按’CTRL-C’取消安装或者指定安装目录。”)如果接受默认安装路径,则会显示“PREFIX=/home//anaconda<2 or 3>”并且继续安装。安装过程大约需要几分钟的时间。
安装器若提示“Do you wish the installer to prepend the Anaconda install location to PATH in your /home//.bash_profile ?”(“你希望安装器添加Anaconda安装路径在/home//.bash_profile文件中吗?”),建议输入“yes”。
注意:
当看到“Thank you for installing Anaconda!”则说明已经成功完成安装。
关闭终端,然后再打开终端以使安装后的Anaconda启动。
验证安装结果。可选用以下任意一种方法:
写在前面
接下来均是以命令行模式进行介绍,Windows用户请打开“Anaconda Prompt”;macOS和Linux用户请打开“Terminal”(“终端”)进行操作。
验证conda已被安装
conda --version
终端上将会以conda 版本号的形式显示当前安装conda的版本号。如:conda 3.11.0
注意:如果出现错误信息,则需核实是否出现以下情况:
更新conda至最新版本
conda update conda
执行命令后,conda将会对版本进行比较并列出可以升级的版本。同时,也会告知用户其他相关包也会升级到相应版本。
当较新的版本可以用于升级时,终端会显示Proceed ([y]/n)?,此时输入y即可进行升级。
查看conda帮助信息
conda --help 或 conda -h
卸载conda
Linux 或 macOS
rm -rf ~/anaconda2 或 rm -rf ~/anaconda3 。即删除Anaconda的安装目录。根据安装的Anaconda版本选择相应的卸载命令。
Windows
控制面板 → 添加或删除程序 → 选择“Python X.X (Anaconda)” → 点击“删除程序”
注意:
写在前面
接下来均是以命令行模式进行介绍,Windows用户请打开“Anaconda Prompt”;macOS和Linux用户请打开“Terminal”(“终端”)进行操作。
创建新环境
conda create --name
如果要安装指定的版本号,则只需要在包名后面以=和版本号的形式执行。如:conda create --name python2 python=2.7,即创建一个名为“python2”的环境,环境中安装版本为2.7的python。
如果要在新创建的环境中创建多个包,则直接在
切换环境
① Linux 或 macOS
source activate
② Windows
activate
③ 提示
退出环境至root
① Linux 或 macOS
source deactivate
② Windows
deactivate
③ 提示
当执行退出当前环境,回到root环境命令后,原本行首以“(env_name)”或“[env_name]”开头的字符将不再显示。
显示已创建环境
conda info --envs 或
conda info -e或 conda env list 结果中星号“*”所在行即为当前所在环境。macOS系统中默认创建的环境名为“base”。
复制环境
conda create --name
删除环境
conda remove --name
查找可供安装的包版本
① 精确查找
conda search --full-name
–full-name为精确查找的参数。
例如:conda search --full-name python即查找全名为“python”的包有哪些版本可供安装。
模糊查找
conda search 注意:
是查找含有此字段的包名。此字段两边不加尖括号“<>”。
例如:conda search py即查找含有“py”字段的包,有哪些版本可供安装。
获取当前环境中已安装的包信息
conda list 。执行上述命令后将在终端显示当前环境已安装包的包名及其版本号。
安装包
① 在指定环境中安装包
conda install --name
例如:conda install --name python2 pandas即在名为“python2”的环境中安装pandas包。
② 在当前环境中安装包
conda install
执行命令后在当前环境中安装包。
例如:conda install pandas即在当前环境中安装pandas包。
③ 使用pip安装包
使用场景当使用conda install无法进行安装时,可以使用pip进行安装。例如:see包。→ 命令pip install
④ 从Anaconda.org安装包
卸载包
① 卸载指定环境中的包
conda remove --name
② 卸载当前环境中的包
conda remove
更新包
更新所有包 conda update --all 或 conda upgrade --all
更新指定包
conda update
注意:
灰色框是输入程序的地方,回车是换行,shift+回车执 行灰色区域的代码,它的结果会直接在下面空白处出现。这就是 Jupyter 交互式 的强大地方,将 Python 脚本分成片段式运行,尤其适合数据分析的摸索调整工 作
用community版就可以;了解PyCharm的界面布局; 设置PyCharm的解释器 ; 调整PyCharm的界面主题与样式
PyCharm安装使用教程
macOS Mojave安装PyCharm 2018.x 最新版
Pycharm 解释器
pyCharm 快速上手指南
pyCharm 快捷键
PyCharm采用“项目(Project)”的方式管理源代码;一个项目通常就是一个完整的程序,包含多个源代码文件 ; 通常项目是以目录的方式保存。
win | mac | |
---|---|---|
快速注释-块注释 来自 | 注释 ctrl+/ | |
格式化代码 | ctrl+alt+L | |
运行 | shift+ctrl+f10 | |
复制行 | ctrl+d | |
调试 | ||
开始调试 | shift+alt+f9 | |
逐行执行 | F7 | |
停止调试 | ctrl + f2 | |
调节格式 | alt + enter | |
快速查看函数的格式 | 按住ctrl键,将鼠标放到函数上,就会显示函数信息,点击进去可以查看函数源码。 |
pip是用于安装和管理软件包的包管理器。
pip名称的由来:pip采用的是递归缩写进行命名的。其名字被普遍认为来源于2处:
“Pip installs Packages”(“pip安装包”)
“Pip installs Python”(“pip安装Python”)
pip编写语言:仅适用于Python
Python中默认安装的版本:
Python 2.7.9及后续版本:默认安装,命令为pip
Python 3.4及后续版本:默认安装,命令为pip3
特点
虚拟环境
python 的虚拟环境可以为一个 python 项目提供独立的解释环境、依赖包等资源,既能够很好的隔离不同项目使用不同 python 版本带来的冲突,而且还能方便项目的发布。
virtualenv 包
virtualenv可用于创建独立的 Python 环境,它会创建一个包含项目所必须要的执行文件。virtualenv将会为它自己的安装目录创建一个环境,这并不与其他virtualenv环境共享库;同时也可以选择性地不连接已安装的全局库
pycharm配置本地python虚拟环境
mac安装python3.7,配置环境变量。因mac自带python2.7环境,平时用的比较多的是python3.7,下面将安装及配置过程需要注意,避免这些坑。
安装软件包python3.7.pkg
进入终端,配置Python3环境变量
open ~/.bash_profile
在文件末尾添加:
export PATH=${PATH}:/Library/Frameworks/Python.framework/Versions/3.7/bin
alias python="/Library/Frameworks/Python.framework/Versions/3.7/bin/python3.7"
让文件生效
source ~/.bash_profile
进入终端,检查python版本
python -v
配置环境变量
快捷键ctrl + R 输入cmd进入命令行界面
命令行中输入python,可以看到已经进入了python环境。
在这个步骤中,如果输入python提示命令未找到,说明环境变量配置失败。我们开始来配置环境变量。
配置环境变量:
方法一:使用命令行配置。
在cmd下输入:path=%path%;后面加上python安装路径。按enter回车即可。
方法二:使用图形界面配置。
桌面我的计算机,右键选择属性
属性里面选择高级,点下面的环境变量
在系统变量值中找到“path”,在系统变量值中输入python的安装路径。(记得先加;分号隔开)配置完成之后确定退出。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FiWmAzaR-1614984312160)(/Users/wu/Library/Application Support/typora-user-images/image-20210123215459993.png)]
再次打开cmd,输入python,即可进入python环境,大功告成!
Python是一种面向对象的解释型计算机程序设计语言,总特点: 语言简洁,上手轻松 ;Python是最好的大数据、人工智能语言 ;庞大的用户群体,成熟的技术体系,遍及人工智能、科学计算、Web开发、系统运维、大数据及云计算、金融、游戏开发等。
解释型语言: 这意味着开发过程中没有了编译这个环节。类似于PHP和Perl语言。
交互式语言: 这意味着,您可以在一个Python提示符,直接互动执行写你的程序。
面向对象语言: 面向对象的语言,拥有各种功能方法即method。意思就是把要处理的对象按照格式放到对应的括号里。这意味着Python支持面向对象的风格或代码封装在对象的编程技术。
**1.易于学习:**Python有相对较少的关键字,结构简单,和一个明确定义的语法,学习起来更加简单。适用于短平快的日常任务
**2.易于阅读:**Python代码定义的更清晰。
**3.易于维护:**Python的成功在于它的源代码是相当容易维护的。
4.一个广泛的标准库:实现其强大功能的前提,就是Python具有数量庞大且功能相对完善的标准库和第三方库。
**5.互动模式:**互动模式的支持,您可以从终端输入并获得结果的语言,互动的测试和调试代码片断。
**6.便携式:**Python可以运行在多种硬件平台和所有平台上都具有相同的接口。
具有跨平台的特点,可以在Linux、macOS以及Windows系统中搭建环境并使用,其编写的代码在不同平台上运行时,几乎不需要做较大的改动,使用者无不受益于它的便捷性。
7.可扩展**(开源)****:**可以添加低层次的模块到Python解释器。这些模块使程序员可以添加或定制自己的工具,更有效。
**8.数据库:**Python提供所有主要的商业数据库的接口。
**9.GUI编程:**Python支持GUI可以创建和移植到许多系统调用。
**10.可扩展性:**相比 shell 脚本,Python 提供了一个更好的结构,且支持大型程序。
Python是由Guido van Rossum在八十年代末和九十年代初,在荷兰国家数学和计算机科学研究所设计出来的。
Python 本身也是由诸多其他语言发展而来的,这包括ABC、Modula-3、C、C++、Algol-68、SmallTalk、Unix shell 和其他的脚本语言等等。像Perl语言一样, Python 源代码同样遵循 GPL(GNU General Public License)协议。现在Python是由一个核心开发团队在维护,Guido van Rossum 仍然占据着至关重要的作用,指导其进展。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pomMTJ7g-1614984312162)(/Users/wu/Library/Application Support/typora-user-images/image-20210123212608467.png)]
python执行过程:源代码 –编译–> 字节码(特定python的表现形式.pyc) –解释–> 机器码
交互式
定义:在命令行输入指令,回车即可得到结果。
步骤:
文件式
1. 定义:将指令编写到.py文件中,可以重复运行程序。
2. 步骤:
1. 创建文件:/home/tarena/1902/month01/day01/hello.py
2. 打开终端进入指定目录 cd /1902/month01/day01
3. 运行python程序 python3 hello.py
建议 3.0 以上,不要选择 2.7 的版本,否则你会被无尽的中文编码问 题困扰。
2.7安装
3.8帮助文档
调试目的
理解程序执行过程、排除逻辑错误(不是Error)
方式
pycharm:
加断点(程序运行到本行停止,没有执行本行)
开始调试shift+alt+f9
逐行执行 F7
停止调试ctrl + f2
GIL是 python的全局解释器锁,进程中假如有多个线程运行,一个线程在运python程序的时候会霸占 python解释器(加了一把锁即G),使该进程内的其他线程无法运行,等该线程运行完后其他线程才能运行。如果线程运行过程中遇到耗时操作解释器锁解开,使其他线程运行。所以在多线程中,线程的运行仍是有先后顺序的,并不是同时进行。多进程中因为每个进程都能被系统分配资源,相当于每个进程有了一个 python解释器所以多进程可以实现多个进程的同时运行,缺点是进程系统资源开销大
异常即是一个事件,该事件会在程序执行过程中发生,影响了程序的正常执行。
一般情况下,在Python无法正常处理程序时就会发生一个异常。
异常是Python对象,表示一个错误。
当Python脚本发生异常时我们需要捕获处理它,否则程序会终止执行。大多数的异常都不会被程序处理,都以错误信息的形式展现在这里
异常类名 | 描述 |
---|---|
Exception | 常规错误的基类,几乎所有的异常都是由此派生而来 |
BaseException | 所有异常的基类 |
AttributeError | 对象没有这个属性,引用属性或者赋值失败 |
SyntaxError | 代码语法错误 |
TypeError | 对类型无效的操作,将内置函数或者操作用于类型不正确时 |
OSError | 操作系统错误类,有多个子类。操作系统不能执行指定的任务时引发 |
LookupError | 无效数据查询的基类 |
IndexError | 序列中没有此索引(index)。为lookupError的子类 |
ZeroDivisionError | 除(或取模)零 (所有数据类型) |
NameError | 未声明/初始化对象 (没有属性) |
ValueError | 传入无效的参数,类型正确但值不合适 |
StopIteration | 迭代器没有更多的值 |
SystemExit | 解释器请求退出 |
KeyboardInterrupt | 用户中断执行(通常是输入^C) |
GeneratorExit | 生成器(generator)发生异常来通知退出 |
StandardError | 所有的内建标准异常的基类 |
ArithmeticError | 所有数值计算错误的基类 |
FloatingPointError | 浮点计算错误 |
OverflowError | 数值运算超出最大限制 |
AssertionError | 断言语句失败 |
EOFError | 没有内建输入,到达EOF 标记 |
EnvironmentError | 操作系统错误的基类 |
IOError | 输入/输出操作失败 |
WindowsError | 系统调用失败 |
ImportError | 导入模块/对象失败 |
KeyError | 映射中没有这个键 |
MemoryError | 内存溢出错误(对于Python 解释器不是致命的) |
UnboundLocalError | 访问未初始化的本地变量 |
ReferenceError | 弱引用(Weak reference)试图访问已经垃圾回收了的对象 |
RuntimeError | 一般的运行时错误 |
NotImplementedError | 尚未实现的方法 |
IndentationError | 缩进错误 |
TabError | Tab 和空格混用 |
SystemError | 一般的解释器系统错误 |
UnicodeError | Unicode 相关的错误 |
UnicodeDecodeError | Unicode 解码时的错误 |
UnicodeEncodeError | Unicode 编码时错误 |
UnicodeTranslateError | Unicode 转换时错误 |
Warning | 警告的基类 |
DeprecationWarning | 关于被弃用的特征的警告 |
FutureWarning | 关于构造将来语义会有改变的警告 |
OverflowWarning | 旧的关于自动提升为长整型(long)的警告 |
PendingDeprecationWarning | 关于特性将会被废弃的警告 |
RuntimeWarning | 可疑的运行时行为(runtime behavior)的警告 |
SyntaxWarning | 可疑的语法的警告 |
UserWarning | 用户代码生成的警告 |
通过创建一个新的异常类,程序可以命名它们自己的异常。异常应该是典型的继承自Exception类的自定义类**
捕捉异常可以使用try/except语句。
try/except语句用来检测try语句块中的错误,从而让except语句捕获异常信息并处理。如果你不想在异常发生时结束你的程序,只需在try里捕获它。
异常的传递
如果异常在产生的地方不被捕获,异常会一层层向外抛出,各层调用程序后的程序则不会执行。
语法:以下为简单的try…except…else的语法:
try:
<语句> #运行别的代码
except <名字>:
<语句> #如果在try部份引发了’name’异常
except <名字>,<数据>:
<语句> #如果引发了’name’异常,获得附加的数据
else:
<语句> #如果没有异常发生
try的工作原理是
实例
下面是简单的例子,它打开一个文件,在该文件中的内容写入内容,但文件没有写入权限,发生了异常:
\#!/usr/bin/python
\# -*- coding: UTF-8 -*-
try:
fh = open("testfile", "w")
fh.write("这是一个测试文件,用于测试异常!!")
except IOError:
print "Error: 没有找到文件或读取文件失败"
else:
print "内容写入文件成功"
fh.close()
# 在执行代码前为了测试方便,我们可以先去掉 testfile 文件的写权限,命令如下:
chmod -w testfile
# 再执行以上代码:
$ python test.py
Error: 没有找到文件或读取文件失败
定义:可以在程序的指定位置手动抛出一个异常,使用 raise 语句即可。
作用:我们从来都是想方设法地让程序正常运行,为什么还要手动设置异常呢?首先要分清楚程序发生异常和程序执行错误,它们完全是两码事,程序由于错误导致的运行异常,是需要程序员想办法解决的;但还有一些异常,是程序正常运行的结果,比如用 raise 手动引发的异常。引发的异常通常用 try except(else finally)异常处理结构来捕获并进行处理。
raise 语句的基本语法格式为:
raise [Exception [, args [, traceback]]]
raise 语句有如下三种常用的用法:
raise:单独一个 raise。该语句引发当前上下文中捕获的异常(比如在 except 块中),或默认引发 RuntimeError 异常。
如果你只想知道这是否抛出了一个异常,并不想去处理它,那么一个简单的 raise 语句就可以再次把它抛出。
当在没有引发过异常的程序使用无参的 raise 语句时,它默认引发:RuntimeError 异常
raise 异常类名称:raise 后带一个异常类名称,表示引发执行类型的异常。
raise 异常类名称(描述信息):在引发指定类型的异常的同时,附带异常的描述信息。
细节错误
细节上的错误,通过 print()打印,能执行到 print()说明一般上面的代码没有问
题,分段检测程序是否有问题,如果是js的话可以 alert或 console. log
第三方框架
如果涉及一些第三方框架,会去查官方文档或者一些技术博客
bug的管理
对于bug的管理与归类总结,一般测试将测试出的bug用 teambin等bug管理工具进
行记录,然后我们会一条一条进行修改,修改的过程也是理解业务逻辑和提高自己编程逻
辑缜密性的方法,我也都会收藏做一些笔记记录
其他问题
导包问题、城市定位多音字造成的显示错误问题
68个内置函数综合整理为12大类。
bin() 将给的参数转换成二进制
otc() 将给的参数转换成八进制
hex() 将给的参数转换成十六进制
print(bin(10)) # 二进制:0b1010
print(hex(10)) # 十六进制:0xa
print(oct(10)) # 八进制:0o12
abs() 返回绝对值
divmode() 返回商和余数
round() 四舍五入
pow(a, b) 求a的b次幂, 如果有三个参数. 则求完次幂后对第三个数取余
sum() 求和
min() 求最小值
max() 求最大值
print(abs(-2)) # 绝对值:2
print(divmod(20,3)) # 求商和余数:(6,2)
print(round(4.50)) # 五舍六入:4
print(round(4.51)) #5
print(pow(10,2,3)) # 如果给了第三个参数. 表示最后取余:1
print(sum([1,2,3,4,5,6,7,8,9,10])) # 求和:55
print(min(5,3,9,12,7,2)) #求最小值:2
print(max(7,3,15,9,4,13)) #求最大值:15
list() 将一个可迭代对象转换成列表
tuple() 将一个可迭代对象转换成元组
print(list((1,2,3,4,5,6))) #[1, 2, 3, 4, 5, 6]
print(tuple([1,2,3,4,5,6])) #(1, 2, 3, 4, 5, 6)
reversed() 将一个序列翻转, 返回翻转序列的迭代器
slice() 列表的切片
lst = "你好啊"
it = reversed(lst) # 不会改变原列表. 返回一个迭代器, 设计上的一个规则
print(list(it)) #['啊', '好', '你']
lst = [1, 2, 3, 4, 5, 6, 7]
print(lst[1:3:1]) #[2,3]
s = slice(1, 3, 1) # 切片用的
print(lst[s]) #[2,3]
str() 将数据转化成字符串’
当对象为字典、类别等类型时的括号、引号一并转化为字符类型
print(str(123)+'456') #123456
format() 与具体数据相关, 用于计算各种小数, 精算等.
s = "hello world!"
print(format(s, "^20")) #剧中
print(format(s, "<20")) #左对齐
print(format(s, ">20")) #右对齐
\# hello world!
\# hello world!
\# hello world!
print(format(3, 'b' )) # 二进制:11
print(format(97, 'c' )) # 转换成unicode字符:a
print(format(11, 'd' )) # ⼗进制:11
print(format(11, 'o' )) # 八进制:13
print(format(11, 'x' )) # 十六进制(⼩写字母):b
print(format(11, 'X' )) # 十六进制(大写字母):B
print(format(11, 'n' )) # 和d⼀样:11
print(format(11)) # 和d⼀样:11
print(format(123456789, 'e' )) # 科学计数法. 默认保留6位小数:1.234568e+08
print(format(123456789, '0.2e' )) # 科学计数法. 保留2位小数(小写):1.23e+08
print(format(123456789, '0.2E' )) # 科学计数法. 保留2位小数(大写):1.23E+08
print(format(1.23456789, 'f' )) # 小数点计数法. 保留6位小数:1.234568
print(format(1.23456789, '0.2f' )) # 小数点计数法. 保留2位小数:1.23
print(format(1.23456789, '0.10f')) # 小数点计数法. 保留10位小数:1.2345678900
print(format(1.23456789e+3, 'F')) # 小数点计数法. 很大的时候输出INF:1234.567890
bytes() 把字符串转化成bytes类型
bs = bytes("今天吃饭了吗", encoding="utf-8")
print(bs) #b'\xe4\xbb\x8a\xe5\xa4\xa9\xe5\x90\x83\xe9\xa5\xad\xe4\xba\x86\xe5\x90\x97
bytearray() 返回一个新字节数组. 这个数字的元素是可变的, 并且每个元素的值得范围是[0,256)
ret = bytearray("alex" ,encoding ='utf-8')
print(ret[0]) #97
print(ret) #bytearray(b'alex')
ret[0] = 65 #把65的位置A赋值给ret[0]
print(str(ret)) #bytearray(b'Alex')
ord() 输入字符找带字符编码的位置
chr() 输入位置数字找出对应的字符
ascii() 是ascii码中的返回该值 不是就返回u
print(ord('a')) # 字母a在编码表中的码位:97
print(ord('中')) # '中'字在编码表中的位置:20013
print(chr(65)) # 已知码位,求字符是什么:A
print(chr(19999)) #丟
for i in range(65536): #打印出0到65535的字符
print(chr(i), end=" ")
print(ascii("@")) #'@'
repr() 返回一个对象的string形式
s = "今天\n吃了%s顿\t饭" % 3
print(s)#今天# 吃了3顿 饭
print(repr(s)) # 原样输出,过滤掉转义字符 \n \t \r 不管百分号%
\#'今天\n吃了3顿\t饭'
字典:dict 创建一个字典
集合:set 创建一个集合4
有去重和排序的功能,因为集合是无序不重复元素
frozenset() 创建一个冻结的集合,冻结的集合不能进行添加和删除操作。
len() 返回一个对象中的元素的个数
sorted() 对可迭代对象进行排序操作 放回新的列表
语法:sorted(Iterable, key=函数(排序规则), reverse=False)
Iterable: 可迭代对象
key: 排序规则(排序函数), 在sorted内部会将可迭代对象中的每一个元素传递给这个函数的参数. 根据函数运算的结果进行排序
reverse: 是否是倒叙. True: 倒叙, False: 正序
lst = [5,7,6,12,1,13,9,18,5]
lst.sort() # sort是list里面的一个方法,
print(lst) #[1, 5, 5, 6, 7, 9, 12, 13, 18]
ll = sorted(lst) # 内置函数. 返回给你一个新列表 新列表是被排序的
print(ll) #[1, 5, 5, 6, 7, 9, 12, 13, 18]
l2 = sorted(lst,reverse=**True**) #倒序
print(l2) #[18, 13, 12, 9, 7, 6, 5, 5, 1]
\#根据字符串长度给列表排序
lst = ['one', 'two', 'three', 'four', 'five', 'six']
def f(s):
returnlen(s)
l1 = sorted(lst, key=f )
print(l1) #['one', 'two', 'six', 'four', 'five', 'three']
enumerate() 获取集合的枚举对象
lst = ['one','two','three','four','five']
for index, el in enumerate(lst,1): # 把索引和元素一起获取,索引默认从0开始. 可以更改
print(index)
print(el)
\# 1
\# one
\# 2
\# two
\# 3
\# three
\# 4
\# four
\# 5
\# five
all() 可迭代对象中全部是True, 结果才是True
any() 可迭代对象中有一个是True, 结果就是True
print(all([1,'hello',**True**,9])) #True
print(any([0,0,0,**False**,1,'good'])) #True
zip() 函数用于将可迭代的对象作为参数, 将对象中对应的元素打包成一个元组, 然后返回由这些元组组成的列表. 如果各个迭代器的元素个数不一致, 则返回列表长度与最短的对象相同
lst1 = [1, 2, 3, 4, 5, 6]
lst2 = ['醉乡民谣', '驴得水', '放牛班的春天', '美丽人生', '辩护人', '被嫌弃的松子的一生']
lst3 = ['美国', '中国', '法国', '意大利', '韩国', '日本']
print(zip(lst1, lst1, lst3)) #
for el in zip(lst1, lst2, lst3):
print(el)
\# (1, '醉乡民谣', '美国')
\# (2, '驴得水', '中国')
\# (3, '放牛班的春天', '法国')
\# (4, '美丽人生', '意大利')
\# (5, '辩护人', '韩国')
\# (6, '被嫌弃的松子的一生', '日本')
reduce
Reduce(fun,seq[,initial])
按照指定的方法将序列中的元素缩减为一个值,最终是一个元素类型。
lamada
匿名函数.又称lambda表达式,用于处理简单业务的函数,不需要显式地定义函数,直接传入匿名函数。用匿名函数有个好处,因为函数没有名字,不必担心函数名冲突。
注意:
案例
以map()函数为例,计算f(x)=x2时,除了定义一个f(x)的函数外,还可以直接传入匿名函数:
list(map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
# [1, 4, 9, 16, 25, 36, 49, 64, 81]
# 匿名函数赋值
f = lambda x: x * x
f
# <**function** at 0x101c6ef28>
f(5)
# 25
# 作为返回值
def build(x, y):
return lambda: x * x + y * y
sum = lambda a,b : a*b
print(sum(7,9))
匿名函数也是一个函数对象,也可以把匿名函数赋值给一个变量,再利用变量来调用该函数:
把匿名函数作为返回值返回,比如:
filter() 过滤 (lamda)
对(序列)可迭代对象进行过滤,返回一个迭代器对象。过滤条件为布尔类型的函数,过滤掉的元素是:执行函数结果为0,留下结果为1的函数。
注意:描述中可迭代对象和序列的描述,输出结果 时要确定对象类型,tumple/list,否返回的是迭代器所在的位置
语法:filter(function. Iterable)
function: 用来筛选的函数. 在filter中会自动的把iterable中的元素传递给function. 然后根据function返回的True或者False来判断是否保留留此项数据 , Iterable: 可迭代对象
def func (i): # 判断奇数
return i % 2 == 1
lst = [1,2,3,4,5,6,7,8,9]
l1 = filter(func, lst) #l1是迭代器
print(l1) #
print(list(l1)) #[1, 3, 5, 7, 9]
map()
会根据提供的函数对可迭代对象中的每一个元素进行映射. 分别去执行 function
将传入的函数依次作用于列表中的的每一个元组,返回一个map对象。
语法 : map(function, iterable)
def f (i): return i
lst = [1,2,3,4,5,6,7,]
it = map(f, lst) # 把可迭代对象中的每一个元素传递给前面的函数进行处理. 处理的结果会返回成迭代器print(list(it)) #[1, 2, 3, 4, 5, 6, 7]
def func ():
a = 10
print(locals()) # 当前作用域中的内容
print(globals()) # 全局作用域中的内容
print("今天内容很多")
func()
\# {
'a': 10}
\# {
'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__':
\# <_frozen_importlib_external.SourceFileLoader object at 0x0000026F8D566080>,
\# '__spec__': None, '__annotations__': {
}, '__builtins__': <module 'builtins'
\# (built-in)>, '__file__': 'D:/pycharm/练习/week03/new14.py', '__cached__': None,
\# 'func': <function func at 0x0000026F8D6B97B8>}
\# 今天内容很多
range() 生成数据
next() 迭代器向下执行一次, 内部实际使⽤用了__ next__()⽅方法返回迭代器的下一个项目
iter() 获取迭代器, 内部实际使用的是__ iter__()⽅方法来获取迭代器
for i in range(15,-1,-5):
print(i)
\# 15
\# 10
\# 5
\# 0
lst = [1,2,3,4,5]
it = iter(lst) # __iter__()获得迭代器
print(it.__next__()) #1
print(next(it)) #2 __next__()
print(next(it)) #3
print(next(it)) #4
eval() 执行字符串类型的代码. 并返回最终结果
exec() 执行字符串类型的代码
compile() 将字符串类型的代码编码. 代码对象能够通过exec语句来执行或者eval()进行求值
s1 = input("请输入a+b:") #输入:8+9
print(eval(s1)) # 17 可以动态的执行代码. 代码必须有返回值
s2 = "for i in range(5): print(i)"
a = exec(s2) # exec 执行代码不返回任何内容
\# 0
\# 1
\# 2
\# 3
\# 4
print(a) #None
\# 动态执行代码
exec("""
def func():
print(" 我是周杰伦")
""" )
func() #我是周杰伦
code1 = "for i in range(3): print(i)"
com = compile(code1, "", mode="exec") # compile并不会执行你的代码.只是编译
exec(com) # 执行编译的结果
\# 0
\# 1
\# 2
code2 = "5+6+7"
com2 = compile(code2, "", mode="eval")
print(eval(com2)) # 18
code3 = "name = input('请输入你的名字:')" #输入:hello
com3 = compile(code3, "", mode="single")
exec(com3)
print(name) #hello
print() : 打印输出
input() : 获取用户输出的内容
print("hello", "world", sep="*", end="@") # sep:打印出的内容用什么连接,end:以什么为结尾,end=' '意思是末尾不换行,加空格
\#hello*world@
hash() : 获取到对象的哈希值(int, str, bool, tuple). hash算法:(1) 目的是唯一性 (2) dict 查找效率非常高, hash表.用空间换的时间 比较耗费内存
s = 'alex'print(hash(s)) #-168324845050430382lst = [1, 2, 3, 4, 5]print(hash(lst)) #报错,列表是不可哈希的 id() : 获取到对象的内存地址s = 'alex'print(id(s)) #2278345368944
f = open('file',mode='r',encoding='utf-8')
try:
f.read()
except:
pass
finally:
f.close()
# 让用户输入一个要导入的模块
**import** os
name = input("请输入你要导入的模块:")
__import__(name) # 可以动态导入模块
Type()
查询变量所指的对象类型
help() : 函数用于查看函数或模块用途的详细说明
isinstance :判断对象的类别
print(help(str)) #查看字符串的用途
>>> isinstance('abc', Iterator)
False
>>> isinstance('abc', Iterable)
True
callable() : 用于检查一个对象是否是可调用的. 如果返回True, object有可能调用失败, 但如果返回False. 那调用绝对不会成功
a = 10
print(callable(a)) #False 变量a不能被调用
\#
**def** **f**():
print("hello")
print(callable(f)) # True 函数是可以被调用的
assert
assert()
“断言”是一个心智正常的检查,确保代码没有做什么明显错误的事情。这些心智正常的检查由 assert 语句执行。如果检查失败,就会抛出异常。在代码中,assert语句包含以下部分:
• assert 关键字;
• 条件(即求值为 True 或 False 的表达式);
• 逗号;
• 当条件为 False 时显示的字符串。
print(dir(tuple)) #查看元组的方法
PEP8是 Python Enhancement Proposal 8的缩写,翻译过来就是 Python增强建议书,也就是Python编码规范。例如:缩进,注释,行限字数,每行之间的空行,空格的使用等
对代码进行标注,增加可读性.
单行注释采用 # 开头
注释可以在语句或表达式行末。实际的应用中会对代码本身注释,不执行进行调试
# 第一个注释
print "Hello, Python!"; # 第二个注释
'''
这是多行注释,使用单引号。
这是多行注释,使用单引号。 这是多行注释,使用单引号。
'''
"""
这是多行注释,使用双引号。
这是多行注释,使用双引号。
这是多行注释,使用双引号。
"""
定义:可以改变原有字符含义的特殊字符
常用的:
\’ \” \””” \n
\t 水平制表格 \0 空字符 \
行
示例: print(“ok”); print(“no”) 一个物理行,两个逻辑行。
隐式换行:所有括号的中的内容都可以换行。
x = 1 + (2+ 3+
显示换行:通过折行符 \ 换行
x = 1 + 2+ 3 \
+4
python缩进来写模块。
使用缩紧来控制类,函数以及其他逻辑判断。
代码块中必须使用相同数目的行首缩进空格数。建议你在每个缩进层次使用 单个制表符 或 两个空格 或 四个空格 , 不能混用.
没有严格缩进,在执行时错,IndentationError: unexpected indent 错如果是 IndentationError: unindent does not match any outer indentation level错误表明,你使用的缩进方式不一致,有的是 tab 键缩进,有的是空格缩进,改为一致即可。
多个语句构成代码组
代码组:缩进相同的一组语句构成一个代码块。
像if、while、def和class这样的复合语句,首行以关键字开始,以冒号( : )结束,该行之后的一行或多行代码构成代码组。
多行语句
一般以新行作为为语句的结束符。可以使用斜杠( \)将一行的语句分为多行显示。
注释不能写在字符串内
换行字符和连结字符后不能有其他函数或者空格,本质上仍然是一段
有换行后需要有连结符
语句中包含[], {} 或 () 括号就不需要使用多行连接符。如下实例:
days = ['Monday', 'Tuesday', 'Wednesday',
'Thursday', 'Friday']
同一行显示多条语句
import sys; x = 'w3cschool';
表示一个功能,制作函数的人叫做函数定义者,使用函数的人叫做函数调用者。
定义:关联一个对象的标识
程序的作用就是用来处理数据,而变量就是用来保存的基本单位;为变量设置“值”的过程,称为“赋值”。
变量存储在内存中的值。这就意味着在创建变量时会在内存中开辟一个空间。基于变量的数据类型,解释器会分配指定内存,并决定什么数据可以被存储在内存中。因此,变量可以指定不同的数据类型,这些变量可以存储整数,小数或字符。
变量语法
变量名 = 表达式
变量名1 = 变量名2 = 表达式
变量名1,变量名2 =表达式1,表达式2
变量赋值
等号(=)用来给变量赋值。Python中的变量不需要声明,变量的赋值操作既是变量声明和定义的过程。一个变量可以通过赋值指向不同类型的对象。
等号(=)运算符左边是一个变量名,等号(=)运算符右边是存储在变量中的
name = “毛主席” #文本
salary = 1938.8 #数字
is_weekend = True #布尔值
多个变量赋值
变量名称
要求:
常见错误
Python使用半角字符 ;大小写错误,Python大小写敏感;英文单词拼写错误
Python标识符
有标识符可以包括英文、数字以及下划线(_),但不能以数字开头。
区分大小写的,所有Python的关键字只包含小写字母。
以下划线开头的标识符是有特殊意义的。
以单下划线开头(_foo)的代表不能直接访问的类属性,需通过类提供的接口进行访问,不能用"from xxx import *"而导入;
以双下划线开头的代表类的私有成员;
以双下划线开头和结尾的(foo)代表python里特殊方法专用的标识,如__init__()代表类的构造函数。
Python保留字符
下面的列表显示了在Python中的保留字。这些保留字不能用作常数或变数,或任何其他标识符名称。
and | exec | not |
---|---|---|
assert | finally | or |
break | for | pass |
class | from | |
continue | global | raise |
def | if | return |
del | import | try |
elif | in | while |
else | is | with |
except | lambda | yield |
数据结构:计算机存储数据、组织数据的容器。包含:数值型(int、bool、)、字符串str、列表list、元组Tuple、字典Dictionary、集合Set 、None:表示不存在的特殊对象; 作用:用来占位 a = None;变量解除绑定
不可变数据类型:数值型、字符串型 string和元组 tuple
不允许变量的值发生变化,如果改变了变量的值,相当于是新建了一个对象,而对于相的值的对象,在内存中则只有一个对象(地址),如下图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tR6pyLko-1614984312164)(/Users/wu/Documents/image-20210201105951984.png)]
可变数据类型:列表list、集合set和字典dict
允许变量的值发生变化,即如果对变量进行 append、+=等这种操作后,只是改变了变量的值,而不会新建一个对象,变量引用的对象的地址也不会变化,不过对于相同的值的不同对象,在内存中则会存在不同的对象,即每个对象都有自己的地址,相当于内存中对于同值的对象保存了多份,这里不存在引用计数,是实实在在的对象。
是指有序的队列,序列中的元素按照添加顺序排列,可以通过索引进行获取。
将数据类型作为函数名即可
函数 | 描述 |
---|---|
int(x [,base]) | 将x转换为一个整数 |
long(x [,base] ) | 将x转换为一个长整数 |
float(x) | 将x转换到一个浮点数 |
complex(real [,imag]) | 创建一个复数 |
str(x) | 将对象 x 转换为字符串 ,返回一个用户易读的表达形式 |
repr(x) | 将对象 x 转换为表达式字符串 ,产生一个解释器易读的表达形式,可以转义字符串中的特殊字符,参数可以是Python的任何对象 |
eval(str) | 用来计算在字符串中的有效Python表达式,并返回一个对象 |
tuple(s) | 将序列 s 转换为一个元组 |
list(s) | 将序列 s 转换为一个列表 |
set(s) | 转换为可变集合 |
dict(d) | 创建一个字典。d 必须是一个序列 (key,value)元组。 |
frozenset(s) | 转换为不可变集合 |
chr(x) | 将一个整数转换为一个字符 |
unichr(x) | 将一个整数转换为Unicode字符 |
ord(x) | 将一个字符转换为它的整数值 |
hex(x) | 将一个整数转换为一个十六进制字符串 |
类别
int整型 | bool | float浮点型 | complex 复数 |
---|---|---|---|
1e6 (10的6次) | true | 0.0 | 3.14j |
100 | flase | 15.20 | 45.j |
-786 | -21.9 | 9.322e-36j | |
080 | 32.3+e18 | .876j | |
-0490 | -90. | -.6545+0J | |
-0x260 | -32.54e100 | 3e+26J | |
0x69 | 70.2-E12 | 4.53e-7j |
创建
当你指定一个值时,Number对象就会被创建
数值的除法(/)总是返回一个浮点数,要获取整数使用//操作符。在混合计算时,Pyhton会把整型转换成为浮点数。
删除
使用del语句删除一些对象引用
您可以通过使用del语句删除单个或多个对象。例如:
del var
del var_a, var_b
定义
一系列字符(数字、字母、下划线)组成的不可变序列容器,存储的是字符编码值。
str用单引号(’ ')或双引号(" ")括起来,s=“a1a2···an”(n>=0)、
转意 \ , ,r可以使得斜杆无效
s='yeshedon\'t' # 斜杆后的单引号转意
print(s)
s1=r'yshedon\'t'
print(s1)
'''
yeshedon't
yshedon\'t
'''
续行符 反斜杠 / 。可以作为,表示下一行是上一行的延续。还可以使用"""…"""或者’’’…’’'跨越多行。三个双引号 或者单引号
str_number = '匪警[110],火警[119],急救中心[120],' \
'道路交通事故报警[122],水上求救专用电话[12395],' \
'天气预报[12121],报时服务[12117],森林火警[12119],电力服务[95598],' \
'红十字会急救台[999],公安短信报警[12110],通用紧急求救[112],' \
'信产部IP/网站备案[010-66411166]'
print(str_number)
字符串拼接
+运算符连接在一起,用*运算符重复。
print(str*2)#输出字符串两次
制表符与换行符
制表符是指增加字符的缩进,在字符串中使用\t
换行符是指为字符串换行输出,在字符串中使用\n
增
str.join(序列)
删除
在' python'与'python'是不同的字符串 ,第一个前面有空格
str.lstrip() 删除左侧空白
str.rstrip() 删除右侧空白
str.strip() 删除两端空白
space_str='helloworld'
print(space_str)
改
str.replace()函数 。字符串替换 ,不能向一个索引位置赋值,比如s[0] = ‘m’
语法:str.replace(原始串,目标串,[替换次数])
示例:"aaabbbccc".replace("b" , "d" ,2) 输出 aaaddbccc
str5='thisisstringexample,wowo,thisisareallystring'
pstr5=str5.replace('is','was')#全部替换
pstr5=str5.replace('is','was',3)#替换次数
print(pstr5)
查找
索引查找:字符串有两种索引方式,从左往右以0开始,从右往左以-1开始。取一段,变量[头下标:尾下标]
print('str')#输出完整字符串
print(str[0])#输出字符串中的第一个字符
print(str[2:5])#输出字符串中第三个至第五个之间的字符串
print(str[2:])#输出从第三个字符开始的字符串
获取字符串的长度
len、
lstr=len(space_str)
print(lstr)
内容查找find :对字符串的进行遍历,存在返回所在位置的索引,不存在则返回
其他函数
函数名称 | 说明 |
---|---|
contains() | 返回表示各str是否含有指定模式的字符串 |
replace() | 替换字符串。 |
lower() | 返回字符串的副本,其中所有字母都转换为小写。 |
upper() | 返回字符串的副本,其中所有字母都转换为大写。 |
split() | 分割字符串,返回字符串中的单词列表。 info_list = info.split(’,’) |
strip() | 删除前导和后置空格。 |
join() | 返回一个字符串,该字符串是给定序列中所有字符串的连接。 |
str.title() | 每个单词首字母大写 |
str.swapcase() | 大小写互换 |
rjust() 方法 | 将字符串靠右, 并在左边填充空格 |
ljust() | |
center() | |
‘end’ | 连接上下行的内容 |
zfill() | 数字的左边填充 0 |
定义
由一系列变量组成的可变序列容器。在内存中按照顺序序列排列和存储,动态变化存储;内存允许扩展,适合存储高频变化的词。
注:
列表实用效率低
在表达结构化的数据方面不足:结构化数据指代有明确属性、规则的数据。
基础操作
创建:[元素] list(可迭代对象)
增加:insert append
删除:remove del
修改:列表名[索引] = 数值
查:索引 切片
索引有正序和倒叙两种。[]:取值左闭右开
name = ['zhan san','bb',3,'jjjjjj','bbbbb','lisi','wang wu','zhan san']
#[]:取值左闭右开
print(name[3])
print(name[1:2])
#index:获取列表的index值,只返回第一次出现的索引值
print(name.index('zhan san'))
”“”结果
jjjjjj
['bb']
0
“”“
# for in :对列表遍历:for(变量)in (可迭代对象)
for a in name :
print(a,name.index(a))#只返回第一次出现的索引值
#增加外部参数,单独写索引
i = 0
for b in name:
print(b,i)
i = i + 1
#len:列表长度,倒叙索引
l = len(name)
n = 0
for m in name:
print(m,-l+n)
n = n + 1
#使用while 遍历
i = 0
while i < l :
print(name[i])
i = i + 1
# del
a=[-1,1,66.25,333,333,1234.5]
print(a)
del a[2:3]
print(a)
del a[:]
print(a)
# [-1, 1, 66.25, 333, 333, 1234.5]
# [-1, 1, 333, 333, 1234.5]
# []
相关函数介绍
方法 | 描述 |
---|---|
list.append(x) | 把一个元素添加到列表的结尾,相当于 a[len(a):] = [x]。 |
list.extend(L) | 列表合并:通过添加指定列表的所有元素来扩充列表,相当于 a[len(a):] = L。 |
list.insert(i, x) | 在指定位置插入一个元素。第一个参数是准备插入到其前面的那个元素的索引,例如 a.insert(0, x) 会插入到整个列表之前,而 a.insert(len(a), x) 相当于 a.append(x) 。 |
list.remove(x) | 删除列表中值为 x 的第一个元素。如果没有这样的元素,就会返回一个错误。 |
list.pop([i]) | 从列表的指定位置删除元素,并将其返回。如果没有指定索引,a.pop()返回最后一个元素。元素随即从列表中被删除。(方法中 i 两边的方括号表示这个参数是可选的,而不是要求你输入一对方括号,你会经常在 Python 库参考手册中遇到这样的标记。) |
list.clear() | 移除列表中的所有项,等于del a[:]。 |
list.index(x) | 返回列表中第一个值为 x 的元素的索引。如果没有匹配的元素就会返回一个错误。 |
list.count(x) | 返回 x 在列表中出现的次数。 |
list.sort() | 对列表中的元素进行排序。 默认升序,倒叙参数reverse=True |
list.reverse() | 倒排列表中的元素。 |
list.copy() | 返回列表的浅复制,等于a[:]。 |
len(list) | 列表长度 |
zip() |
字符串VS列表
列表和字符串都是序列,元素之间有先后顺序。
列表和字符串都属于可迭代对象。
字符串不可变,列表可变。
字符串中每个元素存储字符,而列表可以存储任意类型对象。
转化
Join :将多个字符串拼接为一个列表。
result = “连接符”.join(列表)
Split: 将一个字符串拆分为多个列表。
列表 = “a-b-c-d”.split(“分隔符”)
列表推导式
作用:使用简易方法,将可迭代对象转生成为列表。
语法:
变量 = [表达式 for 变量 in 可迭代对象]
变量 = [表达式 for 变量 in 可迭代对象 if 条件]
如果将 表达式 换为条件 返回 bool值
示例:
\# 传统生成列表写法
list_reuslt = []
for item in list01:
list_reuslt.append(item ** 2)
\# 使用列表推导式生成列表
# 变量=[表达式 for 变量1 in 可迭代对象1 for 变量2 in可迭代对象2]
list_reuslt = [item ** 2 for item in list01]
l_5 = [a for a in l_4 if a> 10]
l_5_1 = [ a> 10 for a in l_4]
定义
由一系列变量组成的不可变序列容器。元组,可以看做是不可变得列表,元组用"()"标识。内部元素用逗号隔开。可以包含可变的对象,比如list列表 构造包含0个或1个元素的tuple是个特殊的问题,所以有一些额外的语法规则。读取方式类似列表
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6qREagQ3-1614984312165)(/Users/wu/Documents/image-20210125183137837.png)]
作用
元组与列表都可以存储一系列变量。
列表会预留内存空间,所以可以增加。
元组会按需分配内存,建议变量数据固定时使用元组,因为通常占用空间小。
基础操作
创建
空元组 tup1 = ()
创建有元素的元组:(元素) tuple(可迭代对象)
**一个元素,需要在元素后添加逗号,**否则为字符串 tup2 = (20,)
print(type((1,)),type((1)),type(('1')))
#
获取元素:索引 切片
删:不能删除,相当于只读列表。
其他
支持运算符 ,+拼接 * 重复
函数
方法及描述 | 实例 |
---|---|
len(tuple) 计算元组元素个数。 | tuple1 = (‘Google’, ‘W3CSchool’, ‘Taobao’) len(tuple1) 3 |
max(tuple) 返回元组中元素最大值。 | >>> tuple2 = (‘5’, ‘4’, ‘8’) >>> max(tuple2) ‘8’ |
min(tuple) 返回元组中元素最小值。 | min(tuple2) ‘4’ |
tuple(seq) 将列表转换为元组。 | >>> list1= [‘Google’, ‘Taobao’, ‘W3CSchool’, ‘Baidu’] >>> tuple1=tuple(list1) >>> tuple1 (‘Google’, ‘Taobao’, ‘W3CSchool’, ‘Baidu’) |
案例
# 可以没有括号
t = 12345, 54321, 'hello!'
print(type(t))
#
## Tuples 是更大表达式的一部分 必须有括号:
u = t, (1, 2, 3, 4, 5)
print(u)
# ((12345, 54321, 'hello!'), (1, 2, 3, 4, 5))
print(t[0])
# 12345
print(t[-1])
# hello!
print(u[1:3])
# ((1, 2, 3, 4, 5),)
print( 'hello!' in t)
# True
t[0] = 2
'''
TypeError: 'tuple' object does not support item assignment
'''
列表与元组的区别
元组 | 列表 |
---|---|
内容不可变 | 内容允许扩展 |
创建后固定不变 | 内存存储动态变化 |
效率最高 | 效率较低 |
用于保存稳定不变的数据 | 运行时数据需要变更时使用 |
保存国家名、元素周期表 | 保存天气数据、股市数据 |
定义:Dictionary ,无序键—值对组成的可变映射容器。
是一种映射类型(mapping type)适合表达可结构化的数据:(键 : 值)对集合,
键必须是唯一且不可变的,如字符串,数字或元组;
序列是以连续的整数为索引,字典以关键字为索引,所以可以是任意不可变类型,可以用数字,字符串或元组充当,而用列表就不行。如果同一个键被赋值两次,后一个值会被记住。
值没有限制:字典可变容器模型,且可存储任意类型对象。
映射(哈希算法):通过键对应值,每条记录无序。
字典也被称为哈希(hash),对应散列值。散列值是某一个数据的唯一标识,哈希值是字典的底层实现:(类似于利用伪随机数建)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uJMvVzu7-1614984312166)(/Users/wu/Documents/image-20210125183736122.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hXFehCGr-1614984312167)(/Users/wu/Documents/image-20210125183223197.png)]
基础操作
创建字典:
一对大括号创建一个空的字典:{}
{键1:值1,键2:值2}
添加/修改:
字典[键] = 表达式
说明:键不存在则创建,键存在则修改。
字典[键] 说明:如果不存在键,则错误。
删除:
字典合并 dict1.update(dict2)
排序:
sorted(dic):默认按照字典的键排序 返回键列表
sorted(dic.items()):按键排序,返回键值元组对列表
其他函数
函数及描述 | |
---|---|
radiansdict.clear() | 删除字典内所有元素 |
radiansdict.copy() | 返回一个字典的浅复制 |
radiansdict.fromkeys() | 创建一个新字典,以序列seq中元素做字典的键,val为字典所有键对应的初始值 |
radiansdict.get(key, default=None) | 返回指定键的值,如果值不在字典中返回default值 |
key in dict | 如果键在字典dict里返回true,否则返回false |
radiansdict.items() | 以列表返回可遍历的(键, 值) 元组数组 |
radiansdict.keys() | 以列表返回一个字典所有的键 |
radiansdict.setdefault(key, default=None) | 和get()类似, 但如果键不存在于字典中,将会添加键并将值设为default |
把字典dict2的键/值对更新到dict里 | |
radiansdict.values() | 以列表返回字典中的所有值 |
len(dict) | 计算字典元素个数,即键的总数 |
str(dict) | 输出字典以可打印的字符串表示 |
type(variable) | 返回输入的变量类型,如果变量是字典就返回字典类型 |
item | 关键字和对应的值可以使用同时解读出来: |
enumerate() | 索引位置和对应值可以使用 同时得到: |
get() |
案例
dict01 = dict(name = 'xaio wan',age = 18,sex = 'girl' ,dept = 'Tec')
for k,v in dict01.items():
print(k,v,hash(k),hash(v))
‘’‘
name xaio wan -1700441203090658280 -2010040295217410337
age 18 -8151653543401241522 18
sex girl -6660217190063160556 -97459984178451761
dept Tec 3953520392532114098 2290544382524738294
’‘’
‘’‘
' output\n# For integers , the hash value is itself\n# The hash value of the same date in one run is the same ,but each run output a different hash value
’‘’
# 值可以没有限制地取任何python对象,既可以是标准的对象,也可以是用户定义的
dict1 = {
"employee" : [ #字典与列表的相互嵌套
{
"name":"张三", "salary":1800},
{
"name":"李四", "salary":2000}
],
"device" : [
{
"id" : "8837120" , "title" : "XX笔记本"},
{
"id" : "3839011" , "title" : "XX台式机"}
],
"asset" :[{
},{
}],
"project" :[{
},{
}]
}
dict4 = dict.fromkeys(['name','sex','hirdate','grade'],'N/A')
print(dict4)
#add,update if there is no new
dict4['dept'] = 'operation'
print(dict4)
#delete
employee = dict4
#1.pop
employee.pop('dept')
print(employee)
#2.popitem,delete the last tuple and out put
print(employee.popitem())
print(employee.popitem())
print(employee)
#3.clear,
print(employee.clear())
# 4.
knights = {
'gallahad': 'thepure', 'robin': 'thebrave'}
for k, v in knights.items():
print(k, v)
定义: 由一系列不重复的变量组成的可变映射容器。集合(set)是一个无序不重复元素的集。相当于只有键没有值的字典,元素都可以看作是key。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QEniANUh-1614984312168)(/Users/wu/Documents/image-20210125202651766.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ev1gsykD-1614984312169)(/Users/wu/Documents/image-20210125202609775.png)]
特点:
础操作
创建空集合:set()
固定集合:不可变的集合。
一般集合
创建具有默认值的集合:{元素1,元素2}
set(可迭代对象)
添加:add 、upset
删除:
set.remove()#当元素不存时会报错
Set.discard() #当元素不存时自动跳过
运算
交集、并集、补集、对称补集、子集、超集
查
#遍历
for c in c1:
print©
#判断存在
a = ‘law’ in c1
print(a)
#父集子集
c3 = {‘Philosophy’,‘Economics’,‘law’}
b = c3.issubset(c1) #是否为子集
print(b)
d = c1.issuperset(c3)
print(d)
案例
c1 = {
'Philosophy','Economics','law','education'}
c2= set(['Economics','Philosophy','Finances','History','Literature'])
#add:添加一个
c1.add('shabi')
print(c1)
# {'Philosophy', 'shabi', 'law', 'education', 'Economics'}
#update (元组、列表) :添加多个
c2.update(['hapi','ersha'])
print(c2)
# {'Philosophy', 'Finances', 'Literature', 'History', 'hapi', 'ersha', 'Economics'}
# s
c1.remove('shabi')#当元素不存时会报错
c1.discard('happi') #当元素不存时自动跳过
print(c1)
#集合的数学运算
c1 = {
'Philosophy','Economics','law','education'}
c2 = set(['Economics','Philosophy','Finances','History','Literature'])
#intersection \ intersection_update
c3 = c1.intersection(c2)
print(1,c3)
c1.intersection_update(c2)
print(2,c1)
c1 = {
'Philosophy','Economics','law','education'}
#union,
c4 = c1.union(c2)
print(3,c4)
#difference 单向差集 : A 中的唯一值 、 symmetric_difference 双向差集:两者中不相同的元素
c5 = c1.difference(c2)
print(4,c5)
c6 = c1.symmetric_difference(c2)
print(5,c6)
c1.difference_update(c2)
print(6,c1)
"""
1 {'Philosophy', 'Economics'}
2 {'Philosophy', 'Economics'}
3 {'Philosophy', 'Finances', 'law', 'Literature', 'History', 'education', 'Economics'}
4 {'education', 'law'}
5 {'Literature', 'History', 'Finances', 'education', 'law'}
6 {'education', 'law'}
"""
Python语言支持以下类型的运算符:
Python 解释器可以作为一个简单的计算器:您可以在解释器里输入一个表达式,它将输出表达式的值。以下假设变量a为10,变量b为21:不同类型的数混合运算时会将整数转换为浮点数
运算符 | 描述 | 实例 |
---|---|---|
+ | 加 - 两个对象相加 | a + b 输出结果 31 |
- | 减 - 得到负数或是一个数减去另一个数 | a - b 输出结果 -11 |
* | 乘 - 两个数相乘或是返回一个被重复若干次的字符串 | a * b 输出结果 210 |
/ | 返回浮点数 | b / a 输出结果 2.1 |
% | 返回除法的余数 | b % a 输出结果 1 |
** | 幂 - 返回x的y次幂 | a**b 为10的21次方 |
// | 返回商的整数部分 | 9//2 输出结果 4 , 9.0//2.0 输出结果 4.0 |
以下假设变量a为10,变量b为20:
运算符 | 描述 | 实例 |
---|---|---|
== | 等于 - 比较对象是否相等 | (a == b) 返回 False。 |
!= | 不等于 - 比较两个对象是否不相等 | (a != b) 返回 True. |
> | 大于 - 返回x是否大于y | (a > b) 返回 False。 |
< | 小于 - 返回x是否小于y。所有比较运算符返回1表示真,返回0表示假。这分别与特殊的变量True和False等价。注意,这些变量名的大写。 | (a < b) 返回 True。 |
>= | 大于等于 - 返回x是否大于等于y。 | (a >= b) 返回 False。 |
<= | 小于等于 - 返回x是否小于等于y。 | (a <= b) 返回 True。 |
注意:1. 符号之间没有空格2. 字符串也可以+ -
以下假设变量a为10,变量b为20:
运算符 | 描述 | 实例 |
---|---|---|
= | 简单的赋值运算符 | c = a + b 将 a + b 的运算结果赋值为 c |
+= | 加法赋值运算符 | c += a 等效于 c = c + a |
-= | 减法赋值运算符 | c -= a 等效于 c = c - a |
*= | 乘法赋值运算符 | c *= a 等效于 c = c * a |
/= | 除法赋值运算符 | c /= a 等效于 c = c / a |
%= | 取模赋值运算符 | c %= a 等效于 c = c % a |
**= | 幂赋值运算符 | c **= a 等效于 c = c ** a |
//= | 取整除赋值运算符 | c //= a 等效于 c = c // a |
按位运算符是把数字看作二进制来进行计算的。Python中的按位运算法则如下:
下表中变量 a 为 60,b 为 13。
运算符 | 描述 | 实例 |
---|---|---|
& | 按位与运算符:参与运算的两个值,如果两个相应位都为1,则该位的结果为1,否则为0 | (a & b) 输出结果 12 ,二进制解释: 0000 1100 |
| | 按位或运算符:只要对应的二个二进位有一个为1时,结果位就为1。 | (a | b) 输出结果 61 ,二进制解释: 0011 1101 |
^ | 按位异或运算符:当两对应的二进位相异时,结果为1 | (a ^ b) 输出结果 49 ,二进制解释: 0011 0001 |
~ | 按位取反运算符:对数据的每个二进制位取反,即把1变为0,把0变为1 | (~a ) 输出结果 -61 ,二进制解释: 1100 0011, 在一个有符号二进制数的补码形式。 |
<< | 左移动运算符:运算数的各二进位全部左移若干位,由"<<"右边的数指定移动的位数,高位丢弃,低位补0。 | a << 2 输出结果 240 ,二进制解释: 1111 0000 |
>> | 右移动运算符:把">>“左边的运算数的各二进位全部右移若干位,”>>"右边的数指定移动的位数 | a >> 2 输出结果 15 ,二进制解释: 0000 1111 |
作用:**比较两个bool值关系。优先级:not and or
短路逻辑
如果and前面的表达式结果为false,后面的表达式不再执行;如果or前面的表达式结果为True,后面的表达式不再执行
建议:将耗时的判断尽量放在后面
以下假设变量 a 为 10, b为 20:
运算符 | 逻辑表达式 | 描述 | 实例 |
---|---|---|---|
and | x and y | 布尔"与" - 如果 x 为 False,x and y 返回 False,否则它返回 y 的计算值。 | (a and b) 返回 20。 |
or | x or y | 布尔"或" - 如果 x 是 True,它返回 x的值,否则它返回 y 的计算值。 | (a or b) 返回 10。 |
not | not x | 布尔"非" - 如果 x 为 True,返回 False 。如果 x 为 False,它返回 True。 | not(a and b) 返回 False |
除了以上的一些运算符之外,Python还支持成员运算符,测试实例中包含了一系列的成员,包括字符串,列表或元组。
运算符 | 描述 | 实例 |
---|---|---|
in | 如果在指定的序列中找到值返回 True,否则返回 False。 | x 在 y 序列中 , 如果 x 在 y 序列中返回 True。 |
not in | 如果在指定的序列中没有找到值返回 True,否则返回 False。 | x 不在 y 序列中 , 如果 x 不在 y 序列中返回 True。 |
sheet = ['shi',123,"ssss",4,5]
a='ss'
if a in sheet:
print(a)
else:
print('not in ')
a = 5
b = a# b和a 指向相同的工作区域
c = 5.0
print(a is b )
print(a is c )#对存储地址进行比较,在面向对象的编程中常见
print(a == c )#纯数字比较。
身份运算符用于比较两个对象的存储单元
运算符 | 描述 | 实例 |
---|---|---|
is | is是判断两个标识符是不是引用自一个对象 | x is y, 如果 id(x) 等于 id(y) , is 返回结果 1 |
is not | is not是判断两个标识符是不是引用自不同对象 | x is not y, 如果 id(x) 不等于 id(y). is not 返回结果 1 |
以下表格列出了从最高到最低优先级的所有运算符:
运算符 | 描述 |
---|---|
** | 指数 (最高优先级) |
~ + - | 按位翻转, 一元加号和减号 (最后两个的方法名为 +@ 和 -@) |
* / % // | 乘,除,取模和取整除 |
+ - | 加法减法 |
>> << | 右移,左移运算符 |
& | 位 ‘AND’ |
^ | | 位运算符 |
<= < > >= | 比较运算符 |
<> == != | 等于运算符 |
= %= /= //= -= += *= **= | 赋值运算符 |
is is not | 身份运算符 |
in not in | 成员运算符 |
not or and | 逻辑运算符 |
将用户输入的字符串保存到变量 接收用户输入 。由于是字符串类型,所以不能够用于计算需要转变变量的类型。
语法格式:变量 = input(“提示信息”) 示例:
mobile = input("请输入您的手机号")
couter=int(num)*20
Python两种输出值的方式: 表达式语句和 print() 函数。(第三种方式是使用文件对象的 write() 方法; 标准输出文件可以用 sys.stdout 引用
定义:%操作符生成一定格式的字符串。因为 str.format() 比较新的函数, 大多数的 Python 代码仍然使用 % 操作符。但是因为这种旧式的格式化最终会从该语言中移除, 应该更多的使用 str.format().
语法:” …%格式….” %(变量)
格式:
%[- + 0 宽度.精度]类型码
- : 左对齐(默认就是右对齐)
+:显示正号
0:左侧空白位置补零
宽度:整个数据输出的宽度(字符大小)
精度:保留小数点后多少位
类型码:%s-字符串、%d整数、%f-浮点数来格式化字符串
定义
name='张三'
age=30
weight=97.8
str3='我的名字是%s,今年%d岁,体重%f.2f公斤'%(name,age,weight)
print(str3)
例如:
\>>> import math
\>>> print('The value of PI is approximately %5.3f.' % math.pi)
The value of PI is approximately 3.142.
print('We are the {} who say "{}!"'.format('knights', 'Ni'))
We are the knights who say "Ni!"
fomat配合索引
数字索引
在括号中的数字用于指向传入对象在 format() 中的位置,位置可以打乱如下所示:
for x in range(1,11):
print('{0:2d}{1:3d}{2:4d}'.format(x,x*x,x*x*x))
关键字索引,如果在 format() 中使用了关键字参数, 那么它们的值会指向使用该名字的参数,关键词即使是用提前申明的关键词,format()中也需要再次申明。位置可以打乱
print('This{food}is{adjective}'.format(food='spam',adjective='absolutelyhorrible'))
s='spam'
b='absolutelyhorrible'
print('This{food}is{adjective}'.format(food=s,adjective=b))
关键词和数字混合索引:关键词位置要对应
print('Thestoryof{1},{0},and{other}.'.format('Bill','Manfred',other='Georg'))
格式
数字格式化
注意’:'格式化输出数字时,需要在{}添加:作为前缀,之后写上数字的格式
示例:
format(1234.567, '0.2f') #小数保留2位 ,0.2f是固定格式,0表示整数
format(1234.567, ',') #千分位分隔符,
account='90i9090'
str=234424324.675
str1=format(str,'0,.5f')
print('$'+str1)
str2='请您向账户{}转账¥{:0,.2f}'.format(account,str)
$234,424,324.67500
请您向账户90i9090转账¥234,424,324.68
‘!a’ (使用 ascii()), ‘!s’ (使用 str()) 和 ‘!r’ (使用 repr()) 可以用于在格式化某个值之前对其进行转化:
import math
print('The value of PI is approximately{}.'.format(math.pi))
# The value of PI is approximately 3.14159265359.
print('The value of PI is approximately {!r}.'.format(math.pi))
# The value of PI is approximately 3.141592653589793.
在 ‘:’ 后传入一个整数, 可以保证该域至少有这么多的宽度。 用于美化表格时很有用。
table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 7678}
for name, phone in table.items():
... print('{0:10} ==> {1:10d}'.format(name, phone))
...
Jack ==> 4098
Dcab ==> 7678
Sjoerd ==> 4127
顺序执行:按照条件的编写顺序。
分支语句:条件选择执行
循环语句:循环执行。
Python条件语句是通过一条或多条语句的执行结果(True或者False)来决定执行的代码块。Python程序语言指定任何非0和非空(null)值为true,0 或者 null为false。
if else
作用:让程序根据条件有选择性的执行语句。
语法:
if 真值表达式: 满足条件执行的语句 else: 不满足条件执行的语句块
if 真值表达式1: 满足条件1执行的语句块 elif 真值表达式2:满足条件2执行的语句 else:以上条件都不满足执行的语句块
说明:
elif 字句可以有0个或者多个。
else 字句最多有1个,只能放在最后。
条件表达式
作用:可以选择性的为变量进行赋值
语法: 变量 = 满足条件的结果 if 条件 else 不满足条件的结果
语句中经常会用到运算法:
if语句:比较运算法、成员运算符、身份运算符
else:赋值运算法
注意:
每个条件后面要使用冒号(:),表示接下来是满足条件后要执行的语句块。
使用缩进来划分语句块,相同缩进数的语句在一起组成一个语句块。
在Python中没有switch – case语句。
由于 python 并不支持 switch 语句,所以多个条件判断,只能用 elif 来实现,如果判断需要多个条件需同时判断时,可以使用 or (或),表示两个条件有一个成立时判断条件成功;使用 and (与)时,表示只有两个条件同时成立的情况下,判断条件才成功。当if有多个条件时可使用括号来区分判断的先后顺序,括号中的判断优先执行,此外 and 和 or 的优先级低于>(大于)、<(小于)等判断符号,即大于和小于在没有括号的情况下会比与或要优先判断
if else 简单的写法 4种:
但是对于数据分析来说,代码的易读性优于简洁性
传统
a, b, c = 1, 2, 3
if a>b:
c = a
else:
c = b
一行表达式,为真时放if前
c = a if a>b else b
二维列表,利用大小判断的0,1当作索引
c= [b, a][a > b]
第四种最有意思了,利用and 的特点,若and前位置为假则直接判断为假。利用 or的特点,若or前位置为真则判断为真。
c = (a>b and [a] or [b])[0]
\# 改编版
c = (a>b and a or b)
# # 从前往后找,and找假,or找真
# 前真返后,
print(111 and 222) # 222
# 前假返前
print(0 and 333) #0
# 若x真【x】, x假,y真【y】,xy假【y】,只有前真返回前
print(111 or 222) #111
print(0 or 222) #222
print('' or 0) # 0
判断语句为None
当判断语句为None时 执行 else 。等同于 条件为false,案例:
a= None
b=2
c=3
c = a if a else b
print(c)
#执行结果:2
for循环和while循环
(在Python中没有do…while循环,)循环语句当条件为正确时,允许我们执行一个语句或语句组多次执行。
while 语句
作用:
在给定的判断条件为 true 时执行循环体,否则退出循环体,
语法:
while 真值表达式:
足条件执行的循环体
else:
条件不满足执行的语句
说明:
for 语句
作用:用来遍历可迭代对象的元素。
语法:
for 变量列表 in 可迭代对象:
循环体
else:
循环过后执行的语句
说明:
break语句
跳出循环体,后面的代码不再执行。break语句终止for和while的循环体,可以让while语句的else部分不执行 。对应的一层循环块将不执行,对应题中,i=2时 j=j+1不在执行,但是内嵌套的while 和 k=i+k还在执行,由于每次k=3,所以只是j=j+1不
for n in range(2,10):
for x in range(2,n):
if n%x==0:
print(n,"equlas",x,'*',n//x)
break
else:
print(n,'is a primenumber')
结果:
3 is a primenumber
4 equlas 2 * 2
5 is a primenumber
5 is a primenumber
5 is a primenumber
6 equlas 2 * 3
7 is a primenumber
7 is a primenumber
7 is a primenumber
7 is a primenumber
7 is a primenumber
8 equlas 2 * 4
9 is a primenumber
9 equlas 3 * 3
continue 语句
跳过本次循环,继续下次循环。仅仅判断本次循环中:剩余语句是否执行。然后继续进行下一轮循环,所以continue禁止直接写在循环语句中,一般单独放在判断语句中。
start=101
end=183
i=100
while i<=1820:
i=i+1#如果这句话放在continue后则不能进行全部的循环
if i%17!=0:
continue#不能被17整除的数字过滤掉,不执行下面的print,直接进入下此
print(i)
pass
它只在语法上需要一条语句但程序不需要执行任何操作.例如:
while True:
… pass
迭代-Iteration
迭代是Python最强大的功能之一,是访问集合元素的一种方式:集合的第一个元素开始访问,直到所有的元素被访问完结束。
range函数
作用:可以生成一系列整数的可迭代对象。
语法:range(开始点,结束点,间隔) 说明:
Eg:
range(3,6) # 3 4 5
range(4) #0 1 2 3
range(1,10,2) #1 3 5 7 9
range(5,0,-2) # 5 3 1
range(4,0,1) # 空
迭代器
迭代器是一个可以记住遍历的位置的对象。字符串,列表或元组对象都可用于创建迭代器。两个基本的方法:iter() 和 next()。迭代器对象可以使用常规for语句进行遍历。
可迭代对象:Iterable:
凡是可作用于for循环的对象都是Iterable 迭代对象类型;
Python的for循环本质上就是通过不断调用next()函数实现的
类别
集合数据类型,如list、tuple、dict、set、str等;
generator,包括生成器和带yield的generator function。
迭代器:Iterator
凡是可作用于next(),__next__函数的对象都是Iterator 迭代器 类型,它们表示一个惰性计算的序列;
list、dict、str等数据类型不是Iterator?Iterator对象表示的是一个数据流,Iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误。Iterator甚至可以表示一个无限大的数据流,例如全体自然数,计算是惰性的,只有在需要返回下一个数据时它才会计算 。而使用list是永远不可能存储全体自然数的,长度是一定的。
Iterator 都是 Iterable
生成器都是Iterator对象,集合数据类型如list、dict、str等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象。
list=[1,3,4,5]
it=iter(list)#创建迭代器对象
print(it)#输出迭代器的下一个元素
print(next(it))
print(next(it))
\#输出
<list_iteratorobjectat0x7ff04815c6a0>
1
3
list=[1,3,4,5]
it=iter(list)
for x in it:
print(x,end="")#print默认是打印一行,结尾加换行。end=' '意思是末尾不换行,加空格
# for 实际上完全等价于 以 next()为基础的判断:
for x in [1, 2, 3, 4, 5]:
pass
# 首先获得Iterator对象:
it = iter([1, 2, 3, 4, 5])
# 循环:
while True:
try:
# 获得下一个值:
x = next(it)
except StopIteration:
# 遇到StopIteration就退出循环
break
#isinstane
# 导入判断模块 collections
from collections.abc import Iterable
>>> isinstance([], Iterable)
True
>>> isinstance({
}, Iterable)
True
>>> isinstance('abc', Iterable)
True
>>> isinstance((x for x in range(10)), Iterable)
True
>>> isinstance(100, Iterable)
False
定义:
使用了 yield 的函数被称为生成器(generator)一边循环一边计算的机制。生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。
不使用return 返回值,而是生成多个值,每次返回一个。在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回yield的值。并在下一次执行 next()方法时从当前位置继续运行。实例使用 yield 实现斐波那契数列.
作用
在循环的过程中不断推算出后续的元素,这样就不必创建完整的list,从而节省大量的空间。
通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。
创建
把一个列表生成式的[]改成()
L = [x * x for x in range(10)]
g = (x * x for x in range(10))
print(l)
print(g)
print(next (g))
print(next (g))
'''
8
at 0x7f96d0cdcc10>
0
1
'''
函数定义中包含yield关键字
主要用于用列表生成式写不出来的数列。每次使用yield后函数就会被冻结并返回,再次每次调用的时候执行时从上次返回的yield语句处继续执行。一个生成器函数可以包含一个或者多个yield
可以使用:next() 逐个调用、for循环全部调用
def fib(max):
n, a, b = 0, 0, 1
while n < max:
print(b)
a, b = b, a + b
n = n + 1
return 'done'
fib(6)
“”“
1
1
2
3
5
8
“”“
def fib_1(max):
n, a, b = 0, 0, 1
while n < max:
yield b
a, b = b, a + b
n = n + 1
a= fib_1(6)
next(a)
# 1
next(a)
# 2
next(a)
# 3
for i in fib_1(7):
print(i)
'''
1
1
2
3
5
8
13
'''
函数(Function)是封装好的代码块, 用于封装一个特定的功能,表示一个行为实现单一或相 关联功能的代码段
类别
Python中预制了很多内置函数
开发者也可以创建自定义函数
特点
隐藏具细节的代码
提高代码的利用率
提高可读性,便于调试
定义语法:
def 函数名(形式参数(形参)1,形参2,..,形参n):
要运行的代码(函数体)
return输出的数据(返回值)
#代码的重用
def hello():#函数名
print("Hello World")#函数体
# 返回值包含多个数据
def get_detail_info():
dict1 = {
"employee" : [ #字典与列表的相互嵌套
{
"name":"张三", "salary":1800},
{
"name":"李四", "salary":2000}
],
"device" : [
{
"id" : "8837120" , "title" : "XX笔记本"},
{
"id" : "3839011" , "title" : "XX台式机"}
],
"asset" :[{
},{
}],
"project" :[{
},{
}]
}
return dict1
print(get_detail_info())
d = get_detail_info()
sal = d.get("employee")[0].get("salary")
print(sal)
#
{
'employee': [{
'name': '张三', 'salary': 1800}, {
'name': '李四', 'salary': 2000}], 'device': [{
'id': '8837120', 'title': 'XX笔记本'}, {
'id': '3839011', 'title': 'XX台式机'}], 'asset': [{
}, {
}], 'project': [{
}, {
}]}
1800
说明:
def关键字,全称define,意为”定义”。
函数名:建议使用动词,对函数体中语句的描述。
形参列表:形式参数 。方法定义者要求调用者提供的信息
函数体:完成该功能的语句。建议语句不要太多
返回值:方法定义者告诉调用的结果。语法:return 结果。说明:
不写return关键字,相当于返回None
return 还意味着方法结束
虽然每个函数对应一个返回值,但这个返回值可以是字典/或类似字典的结构
补充
局部/全局:
定义在函数内部的变量拥有一个局部作用域,定义在函数外的拥有全局作用域。
查找规则:LEGB
类型:
定义:
参数就是函数的输入数据,在程序运行时根据参数不同执行不同代码。。
形参是parameter,实参是argument。
形参”全称为"形式参数" 本质是一个名字,不占用内存空间
由于它不是实际存在变量,所以又称虚拟变量。用于定义函数名和函数体的时候使用的参数,目的是用来接收调用该函数时传入的参数。只有在程序执行过程中调用了函数,形参才有可能得到具体的值,并参与运算求得函数值。
实参的本质是一个变量,已经占用内存空间。
实参” 实际参数。在调用有参函数时,函数名后面括号中的参数实参可以是常量、变量或表达式。在调用函数时,实参将赋值给形参。因而,必须注意实参的个数,类型应与形参一一对应,并且必须要有确定的值。
案例
def print_verse(verse_name, is_show_title, is_show_dynasty):#形参
# 函数体
if verse_name == "静夜思":
if is_show_title == True:
print("静夜思-李白")
if is_show_dynasty == True:
print("唐朝")
print("床前明月光")
print("疑是地上霜")
print("举头望明月")
print("低头思故乡")
elif verse_name == "再别康桥":
if is_show_title == True:
print("再别康桥-徐志摩")
if is_show_dynasty == True:
print("民国")
print("轻轻地我走了")
print("正如我轻轻地来")
print("挥一挥手")
print("不带走一片云彩")
print_verse("静夜思", True, False)#实参
print("...")
print_verse("再别康桥", True, True)#实参
实参传递方式
位置传参实参与形参的位置依次对应。
序列传参实参用*将序列拆解后与形参的位置依次对应
关键字传参 实参根据形参的名字进行对应。
字典传参 :实参用**将字典拆解与形参的名字进行对应。
参数传递的*args和**kwargs。允许定义的函数接受任意数目的参数。
主要是用于将不定数的参数传递给一个函数:预先并不知道函数使用者会传递多少个参数给。
*args:是用来发送一个非键值对的可变数量的参数列表给一个函数:
**kwargs:允许你将不定长度的键值对作为参数传递给一个函数。如果你想要在一个函数里处
理带名字的参数你应该使用* kwargs。r
传递规则和语法
位置形参 --> 星号元组形参 --> 命名关键字形参 --> 双星号字典形参
def fun1(a,b,*args,c,d,**kwargs):
print(a,b, args,c,d, kwargs)
默认(缺省)参数
def 函数名(参数1 = 默认值1):
函数体
说明:
位置形参
def 函数名(参数1):
函数体
星号元组形参
def 函数名(*args):
函数体
命名关键字形参
def 函数名(*,参数名):
函数体
def 函数名(*args,参数名):
函数体
作用:强制实参使用关键字传递
双星号字典形参
def 函数名(**kwargs):
函数体
可变/不可变类型在传参时的区别:
不可变类型的数据传参时,函数内部不会改变原数据的值。
不可变类型:字符串、元组、固定集合、整数、浮点数、复数。
可变类型的数据传参时,函数内部可能改变原数据的值。
可变类型列表、字典、集合
参数使用技巧
# 1.设置参数默认值,关**键字参数形式** :只需要在形参后面增加 "= 具体值" 即可
def parrot(voltage,state='astiff',action='voom',type='NorwegianBlue'):
print("--this parrot would't",action,end='')
print("if you put",voltage,"voltsthroughit.")
print("--lovelyplumage,the",type)
\#几种方式被调用:
parrot(1000) # 位置1参数
parrot(voltage=1000) # 关键词参数
parrot('amillion', 'bereftoflife', 'jump') # 位置参数
parrot(voltage=1000000, action='VOOOOOM') # 2关键词
parrot(action='VOOOOOM', voltage=1000000) # 2关键词位置可换
parrot('athousand', state='pushingupthedaisies') # 1关键词,位置
\#错误调用方法:
parrot()#required argument missing缺少参数
parrot(voltage=5,'dead')#non-key word argument after a key word argument第二个参数无效
parrot(110,voltage=220)#duplicate value for the same argument相同参数重复
parrot(actor='JohnCleese')#unknown key word argument未必参数
#2. 关键词
def calc_exchange_rate(amt,source,target):
if source == "CNY" and target =="USD":
#3. 混合形式传参, * 代表之后所有参数传参时必须使用关键字传参
def health_check1(name, age, *, height, weight, hr, hbp, lbp, glu):
print("您的健康状况良好")
health_check1("张三", 32, height=178, weight=85.5, hr=70, hbp=120,
# 3.序列传参* (实际很少用)
def calc(a,b,c):
return a+b+c
r = calc(1,2,3)
print(r)
l = [1,2,3]
print(calc(*l))
# 4. 字典传参 **,注意key和参数要对应,字典中的key书写为字符串格式
def health_check(name, age, height, weight, hr, hbp, lbp, glu):
print(name)
print(height)
print(hr)
print("您的健康状况良好")
param = {
"name": "张三", "height": 178, "age": 32, "weight": 85.6, "hr": 70, "hbp": 120, "lbp": 80, "glu": 4.3}
health_check(**param)
# 5. 变参数列表
”“”
让函数调用可变个数的参数.这些参数被包装进一个元组(查看元组和序列).在这些可变个数的参数之前,可以有零到多个普通的参数
“”“
定义:
模块是包含函数和变量的文件,其后缀名是.py。模块可以被别的程序引入,以使用该模块中的函数等功能。这也是使用python标准库的方法。
作用:
可维护性更强
各个功能分别作为一个模块,分别维护修改。
可以定义多个函数和变量。
方便代码重用
各个模块可以反复被各个程序调用,同时避免函数名和变量名冲突
导入及定位
导入
import 语句。当解释器遇到 import 语句,如果模块在当前的搜索路径就会被导入。一个模块只会被导入一次 不管你执行了多少次import这样可以防止导入模块被一遍又一遍地执行。
定位
Python的搜索路径:
当前包 —>内置函数—>sys.path(环境变量).首先会在当前的目录进行查找,然后在内置函数中查找,最后在环境变量中查找
搜索路径
搜索路径是由一系列目录名组成的,搜索路径被存储在sys模块中的path变量,Python解释器就依次从这些目录中去寻找所引入的模块。这看起来很像环境变量,事实上,也可以通过定义环境变量的方式来确定搜索路径。搜索路径是在Python编译或安装的时候确定的,安装新的库应该也会修改
sys.path
查看
sys.path输出是一个列表,
其中第一项是空串’’,代表当前目录(若是从一个脚本中打印出来的话,可以更清楚地看出是哪个目录),亦即我们执行python解释器的目录(对于脚本的话就是运行的脚本所在的目录)
修改
sys.path.append将自定义模块的路径添加到系统的环境变量(sys.path)中
import sys
sys.path
['', '/Library/Frameworks/Python.framework/Versions/3.7/lib/python37.zip', '/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7', '/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/lib-dynload', '/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages']
sys.path.append('/Users/wu/Desktop')
sys.path
['', '/Library/Frameworks/Python.framework/Versions/3.7/lib/python37.zip', '/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7', '/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/lib-dynload', '/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages', '/Users/wu/Desktop']
模块属性
dir——列出对象的所有属性及方法
内置的函数 dir() 可以找到模块内定义的所有名称。以一个字符串列表的形式返回,如果没有给定参数,那么 dir() 函数会罗列出当前定义的所有名称,给定参数,这些参数可以进一步dir:
底下是双下划线的属性是系统内置的属性,
dir(hello)
['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'fun']
dir(hello.__name__)
['__add__', ………… ‘zfill']
hello.__name__
'hello'
# __doc__——模块的文档
hello.__doc__
'\n文档注释\n这是hello模块,自己定义的模块\n'
# __file__——文件全路径
hello.__file__
'/Users/wu/Desktop/hello.py'
help——查看类,方法的帮助信息
如果没有给定参数,那么 help() 函数会罗列出当前定义的所有名称,给定参数,这些参数可以进一步help(hello.add)。
帮助文档:[mac](file:///Library/Frameworks/Python.framework/Versions/3.7/Resources/English.lproj/Documentation/library/index.html )
这是编写模块的关键,用于帮助文档的调用者,所以写注释要完善而规范,细节规范在pycharm中会有相对应的建议。比如:编码前对模块的功能描述、编写中写好每一步的规范:参数、返回值
python标准库中模块
标准模块:The Python Standard Library
Python 本身带着一些标准的模块库,在 Python 库参考文档中将会介绍到(就是后面的"库参考文档")。有些模块直接被构建在解析器里,这些虽然不是一些语言内置的功能,但是他却能很高效的使用,甚至是系统级调用也没问题。这些组件会根据不同的操作系统进行不同形式的配置,比如 winreg 这个模块就只会提供给 Windows 系统。
包的简介
包是一种管理 Python 模块命名空间的形式,采用"点模块名称"。比如一个模块的名称是 A.B, 那么他表示一个包 A中的子模块 B 。不同的作者都可以提供 NumPy 模块,或者是 Python 图形库。采用点模块名称这种形式也不用担心不同库之间的模块重名的情况。
作用
可以用来组织模块(可以包含其它模块的模块)
模块重名问题解决
建立
目录必须包含文件_init_.py.这也是包 package 和模块的区别
引入整个包:
包的引用 import module
路径
在导入一个包的时候,Python 会根据 sys.path 中的目录来寻找这个包中包含的子目录。
_init_.py\ __
目录只有包含一个叫做 init.py 的文件才会被认作是一个包,主要是为了避免一些滥俗的名字(比如叫做 string)不小心的影响搜索路径中的有效模块。 (init.py相当于把自身整个文件夹当作一个包来管理,每当有外部import的时候,就会自动执行里面的函数)。
用户可以每次只导入一个包里面的特定模块,必须使用全名去访问,比如:
import xiaowu.pay #将会导入子模块:xiaowu.pay
help(pay) #访问会出错
help(xiaowu.pay)#必须使用全名去访问:
from package import item只引入所需要的属性和方法
这种形式的时候,对应的item既可以是包里面的子模块(子包),或者包里面定义的其他名称,比如函数,类或者变量。
import语法会首先把item当作一个包定义的名称,如果没找到,再试图按照一个模块去导入。如果还没找到,恭喜,一个:exc:ImportError 异常被抛出了。反之,如果使用形如import item.subitem.subsubitem这种导入形式,除了最后一项,都必须是包,而最后一项则可以是模块或者是包,但是不可以是类,函数或者变量的名字。
从当前目录引入
from . import xx
from module.xx.xx import xx
指定别名:from module.xx.xx import xx as rename
引入所有: from module.xx.xx import *
设置Python模块的搜索路径有几种方式?
设置PYTHONPATH环境变量
mac 通过 终端 添加PYTHONPATH:
永久设置模块的搜索路径
临时设置
进入终端,找到对应文件
添加临时路径:
export PYTHONPATH =“对应的路径”
运行程序 程序
通过添加.pth文件
在site-packages添加一个路径文件,如mypkpath.pth,必须以.pth为后缀,写上你要加入的模块文件所在的目录名称就是了
需要在Python的相关目录中放置一个名称是ze,扩展名是.pth
这个文件的每一行就是一个路径。
当Python运行程序时。当Python运行脚本时,它就会自动的搜索这个文件。如果找到,就会将对应的路径添加到途径的添加到系统路径中。
在哪一个文件中放置这个.pth文件?
在Python中。
通过设置sys.path
import sys
查看sys.path
添加sys.path.append(“c:\”)
通过PyCharm,可以直接设置
模块文件》make directory as 》source root
永久设置Python模块搜索路径。
临时设置Python模块的搜索路径。
标准库
标准库的意思表示这是一个Python内置模块**,不需要额外下载,目前Python内置模块大概有300个。可以在这里查看Python所有的内置模块:Python内置模块。
可用性注释
由 site 模块添加的常量
逻辑值检测
布尔运算 — and, or, not
比较运算
数字类型 — int, float, complex
迭代器类型
序列类型 — list, tuple, range
文本序列类型 — str
二进制序列类型 — bytes, bytearray, memoryview
集合类型 — set, frozenset
映射类型 — dict
上下文管理器类型
其他内置类型
特殊属性
基类
具体异常
警告
异常层次结构
string — 常见的字符串操作
re — 正则表达式操作
difflib — 计算差异的辅助工具
textwrap — 文本自动换行与填充
unicodedata — Unicode 数据库
stringprep — 因特网字符串预备
readline — GNU readline 接口
rlcompleter — GNU readline 的补全函数
struct — 将字节串解读为打包的二进制数据
codecs — 编解码器注册和相关基类
datetime — 基本的日期和时间类型
calendar — 日历相关函数
collections — 容器数据类型
collections.abc — 容器的抽象基类
heapq — 堆队列算法
bisect — 数组二分查找算法
array — 高效的数值数组
weakref — 弱引用
types — 动态类型创建和内置类型名称
copy — 浅层 (shallow) 和深层 (deep) 复制操作
pprint — 数据美化输出
reprlib — 另一种 repr() 实现
enum — 对枚举的支持
numbers — 数字的抽象基类
math — 数学函数
cmath — 关于复数的数学函数
decimal — 十进制定点和浮点运算
fractions — 分数
random — 生成伪随机数
statistics — 数学统计函数
itertools — 为高效循环而创建迭代器的函数
functools — 高阶函数和可调用对象上的操作
operator — 标准运算符替代函数
pathlib — 面向对象的文件系统路径
os.path — 常用路径操作
fileinput — 迭代来自多个输入流的行
stat — 解析 stat() 结果
filecmp — 文件及目录的比较
tempfile — 生成临时文件和目录
glob — Unix 风格路径名模式扩展
fnmatch — Unix 文件名模式匹配
linecache — 随机读写文本行
shutil — 高阶文件操作
pickle — Python 对象序列化
copyreg — 注册配合 pickle 模块使用的函数
shelve — Python 对象持久化
marshal — 内部 Python 对象序列化
dbm — Unix “数据库” 接口
sqlite3 — SQLite 数据库 DB-API 2.0 接口模块
zlib — 与 gzip 兼容的压缩
gzip — 对 gzip 格式的支持
bz2 — 对 bzip2 压缩算法的支持
lzma — 用 LZMA 算法压缩
zipfile — 使用ZIP存档
tarfile — 读写tar归档文件
csv — CSV 文件读写
configparser — 配置文件解析器
netrc — netrc 文件处理
xdrlib — 编码与解码 XDR 数据
plistlib — 生成与解析 Mac OS X .plist 文件
hashlib — 安全哈希与消息摘要
hmac — 基于密钥的消息验证
secrets — 生成安全随机数字用于管理密码
os — 多种操作系统接口
io — 处理流的核心工具
time — 时间的访问和转换
argparse — 命令行选项、参数和子命令解析器
getopt — C 风格的命令行选项解析器
logging — Python 的日志记录工具
logging.config — 日志记录配置
logging.handlers — 日志处理
getpass — 便携式密码输入工具
curses — 终端字符单元显示的处理
curses.textpad — Text input widget for curses programs
curses.ascii — Utilities for ASCII characters
curses.panel — curses 的 panel 栈扩展
platform — 获取底层平台的标识数据
errno — 标准 errno 系统符号
ctypes — Python 的外部函数库
threading — 基于线程的并行
multiprocessing — 基于进程的并行
multiprocessing.shared_memory — 可从进程直接访问的共享内存
concurrent 包
concurrent.futures — 启动并行任务
subprocess — 子进程管理
sched — 事件调度器
queue — 一个同步的队列类
_thread — 底层多线程 API
_dummy_thread — _thread 的替代模块
dummy_threading — 可直接替代 threading 模块。
上下文变量
手动上下文管理
asyncio 支持
asyncio — 异步 I/O
socket — 底层网络接口
ssl — 套接字对象的TLS/SSL封装
select — 等待 I/O 完成
selectors — 高级 I/O 复用库
asyncore — 异步socket处理器
asynchat — 异步 socket 指令/响应 处理器
signal — 设置异步事件处理程序
mmap — 内存映射文件支持
email — 电子邮件与 MIME 处理包
json — JSON 编码和解码器
mailcap — Mailcap 文件处理
mailbox — Manipulate mailboxes in various formats
mimetypes — Map filenames to MIME types
base64 — Base16, Base32, Base64, Base85 数据编码
binhex — 对binhex4文件进行编码和解码
binascii — 二进制和 ASCII 码互转
quopri — 编码与解码经过 MIME 转码的可打印数据
uu — 对 uuencode 文件进行编码与解码
html — 超文本标记语言支持
html.parser — 简单的 HTML 和 XHTML 解析器
html.entities — HTML 一般实体的定义
XML处理模块
xml.etree.ElementTree — ElementTree XML API
xml.dom — The Document Object Model API
xml.dom.minidom — Minimal DOM implementation
xml.dom.pulldom — Support for building partial DOM trees
xml.sax — Support for SAX2 parsers
xml.sax.handler — Base classes for SAX handlers
xml.sax.saxutils — SAX 工具集
xml.sax.xmlreader — Interface for XML parsers
xml.parsers.expat — Fast XML parsing using Expat
webbrowser — 方便的Web浏览器控制器
cgi — Common Gateway Interface support
cgitb — 用于 CGI 脚本的回溯管理器
wsgiref — WSGI Utilities and Reference Implementation
urllib — URL 处理模块
urllib.request — 用于打开 URL 的可扩展库
urllib.response — urllib 使用的 Response 类
urllib.parse — Parse URLs into components
urllib.error — urllib.request 引发的异常类
urllib.robotparser — robots.txt 语法分析程序
http — HTTP 模块
http.client — HTTP 协议客户端
ftplib — FTP 协议客户端
poplib — POP3 protocol client
imaplib — IMAP4 protocol client
nntplib — NNTP protocol client
smtplib —SMTP协议客户端
smtpd — SMTP 服务器
telnetlib — Telnet client
uuid — UUID objects according to RFC 4122
socketserver — A framework for network servers
http.server — HTTP 服务器
http.cookies — HTTP状态管理
http.cookiejar —— HTTP 客户端的 Cookie 处理
xmlrpc — XMLRPC 服务端与客户端模块
xmlrpc.client — XML-RPC client access
xmlrpc.server — Basic XML-RPC servers
ipaddress — IPv4/IPv6 操作库
audioop — Manipulate raw audio data
aifc — Read and write AIFF and AIFC files
sunau — 读写 Sun AU 文件
wave — 读写WAV格式文件
chunk — 读取 IFF 分块数据
colorsys — 颜色系统间的转换
imghdr — 推测图像类型
sndhdr — 推测声音文件的类型
ossaudiodev — Access to OSS-compatible audio devices
gettext — 多语种国际化服务
locale — 国际化服务
turtle — 海龟绘图
cmd — 支持面向行的命令解释器
shlex — Simple lexical analysis
tkinter — Tcl/Tk的Python接口
tkinter.ttk — Tk主题小部件
tkinter.tix — Extension widgets for Tk
tkinter.scrolledtext — 滚动文字控件
IDLE
其他图形用户界面(GUI)包
typing — 类型标注支持
pydoc — 文档生成器和在线帮助系统
doctest — 测试交互性的Python示例
unittest — 单元测试框架
unittest.mock — 模拟对象库
unittest.mock 上手指南
2to3 - 自动将 Python 2 代码转为 Python 3 代码
test — Python回归测试包
test.support — Utilities for the Python test suite
test.support.script_helper — Utilities for the Python execution tests
审计事件表
bdb — Debugger framework
faulthandler — Dump the Python traceback
pdb — Python的调试器
Python Profilers 分析器
timeit — 测量小代码片段的执行时间
trace — 跟踪Python语句的执行
tracemalloc — 跟踪内存分配
distutils — 构建和安装 Python 模块
ensurepip — Bootstrapping the pip installer
venv — 创建虚拟环境
zipapp — Manage executable Python zip archives
sys — 系统相关的参数和函数
sysconfig — Provide access to Python’s configuration information
builtins — 内建对象
main — 顶层脚本环境
warnings — Warning control
dataclasses — 数据类
contextlib — 为 with语句上下文提供的工具
abc — 抽象基类
atexit — 退出处理器
traceback — 打印或检索堆栈回溯
future — Future 语句定义
gc — 垃圾回收器接口
inspect — 检查对象
site —— 指定域的配置钩子
code — 解释器基类
codeop — 编译Python代码
zipimport — 从 Zip 存档中导入模块
pkgutil — 包扩展工具
modulefinder — 查找脚本使用的模块
runpy — Locating and executing Python modules
importlib — import 的实现
Using importlib.metadata
parser — 访问 Python 解析树
ast — 抽象语法树
symtable — Access to the compiler’s symbol tables
symbol — 与 Python 解析树一起使用的常量
token — 与Python解析树一起使用的常量
keyword — 检验Python关键字
tokenize — 对 Python 代码使用的标记解析器
tabnanny — 模糊缩进检测
pyclbr — Python module browser support
py_compile — Compile Python source files
compileall — Byte-compile Python libraries
dis — Python 字节码反汇编器
pickletools — pickle 开发者工具集
formatter — 通用格式化输出
Windows系统相关模块
msilib — Read and write Microsoft Installer files
msvcrt — 来自 MS VC++ 运行时的有用例程
winreg — Windows 注册表访问
winsound — Sound-playing interface for Windows
posix — 最常见的 POSIX 系统调用
pwd — 用户密码数据库
spwd — The shadow password database
grp — 组数据库
crypt — Function to check Unix passwords
termios — POSIX 风格的 tty 控制
tty — 终端控制功能
pty — 伪终端工具
fcntl — The fcntl and ioctl system calls
pipes — 终端管道接口
resource — Resource usage information
nis — Sun 的 NIS (黄页) 接口
Unix syslog 库例程
optparse — 解析器的命令行选项
imp — Access the import internals
平台特定模块
在这个标准库以外还存在成千上万并且不断增加的其他组件 (从单独的程序、模块、软件包直到完整的应用开发框架),访问 Python 包索引 即可获取这些第三方模块
open() 方法
open() 方法用于打开一个文件,并返回文件对象,在对文件进行处理过程都需要使用到这个函数,如果该文件无法被打开,会抛出 OSError。
**注意:**使用 open() 方法一定要保证关闭文件对象,即调用 close() 方法。
语法
open(file, mode=‘r’) 文件名(file)和模式(mode)。
file: | 必需,文件路径(相对或者绝对路径)。 |
---|---|
mode: | |
buffering: | 设置缓冲 |
encoding: | 一般使用utf8 |
errors: | 报错级别 |
newline: | 区分换行符 |
closefd: | 传入的file参数类型 |
opener: |
file 必须,文件路径(相对或者绝对路径)。
[Python路径无效问](https://blog.csdn.net/Along1617188/article/details/98196297?ops_request_misc=&request_id=&biz_id=102&utm_term=python 路径引用失败&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduweb~default-1-98196297> )题:推荐 r 或者 反斜杆
两个斜杠:\(第一个\是转义符) | \ | win | path2 = ‘C:\Users\Hjx\Desktop\text.txt’ |
---|---|---|---|
单个反斜杠 | / | 通用 :win liux | path1 = ‘C:/Users/Hjx/Desktop/text.txt’ |
r 用于防止字符转义 | path3 = r’C:\Users\Hjx\Desktop\text.txt’ |
mode 可选,文件打开模式
判断逻辑
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bcTjVpET-1614984312171)(/Users/wu/Documents/image-20210126141753228.png)]
基础模式
模式 | r | r+ | w | w+ | a | a+ |
---|---|---|---|---|---|---|
读 | + | + | + | + | ||
写 | + | + | + | + | + | |
创建 | + | + | + | + | ||
覆盖 | + | + | ||||
指针在开始 | + | + | + | + | ||
指针在结尾 | + | + |
全部模式
模式 | 描述 |
---|---|
t | 文本模式 (默认)。 |
x | 写模式,新建一个文件,如果该文件已存在则会报错。 |
b | 二进制模式。与其他模式结合使用,不能单独 |
+ | 打开一个文件进行更新(可读可写)。与其他模式结合使用,不能单独 |
U | 通用换行模式(不推荐)。 |
r | 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。 |
rb | 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。一般用于非文本文件如图片等。 |
r+ | 打开一个文件用于读写。文件指针将会放在文件的开头。 |
rb+ | 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。一般用于非文本文件如图片等。 |
w | 打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 |
wb | 以二进制格式打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。一般用于非文本文件如图片等。 |
w+ | 打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被覆盖。如果该文件不存在,创建新文件。 |
wb+ | 以二进制格式打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。一般用于非文本文件如图片等。 |
a | 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
ab | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
a+ | 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。 |
ab+ | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。 |
函数
序号 | Python File(文件) 方法 | 方法及描述 | ||
---|---|---|---|---|
查 | 内容 | f.read() | 运行第一次.read()之后,光标位于末尾,再次读取输出为空 参数 size未给定或为负则读取所有 | |
读取所有行并返回列 | [file.readlines(sizeint]) | 若给定sizeint>0,则是设置一次读多少字节,这是为了减轻读取压力 | ||
逐行读取 | [file.readline(size]) | 从上一步的文件读位置开始读取整行,包括 “\n” 字符。 一次性读取一行 f.readline(n):读取该行的前n个字符 | ||
文件当前位置 | file.tell() 返回 | |||
改 | 关标位置 | [file.seek(offset, whence]) | # 运行第一次.read()之后,光标位于末尾,再次读取输出为空,所以现在用 f.seek(0) 来移动光标 设置指针位置,offset偏移量,从offset+1读取 | f.seek(0) print(f.read()) print('第二次读取) |
关闭文件 | file.close() | 关闭文件。关闭后文件不能再进行读写操作。 | ||
With as | 避免因读取文件时异常的发生而没有关闭问题的处理了 来自 https://blog.csdn.net/lxy210781/article/details/81176687 | with open(r’c:\test.txt’, ‘r’) as f: data = f.read() | ||
刷新文件内部缓冲 | file.flush() | ,直接把内部缓冲区的数据立刻写入文件, 而不是被动的等待输出缓冲区写入。 | ||
增加 | ||||
写入符串 | file.write(str) | 将字符串写入文件,返回的是写入的字符长度。 | ||
file.writelines(sequence) | 向文件写入一个序列字符串列表,如果需要换行则要自己加入每行的换行符。 | |||
file.fileno() | 返回一个整型的文件描述符(file descriptor FD 整型), 可以用在如os模块的read方法等一些底层操作上。 | |||
file.isatty() | 如果文件连接到一个终端设备返回 True,否则返回 False。 | |||
file.next() | 返回文件下一行。 | |||
[file.truncate(size]) | 截取文件,截取的字节通过size指定,默认为当前文件位置。 |
定义
在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator),扩展原函数的功能。decorator就是接受一个函数作为参数,并返回一个函数。
一句话解释什么样的语言能够用装饰器? 函数可以作为参数传递的语言,可以使用装饰器
语法
def log(func):
def wrapper(*args, **kw):
print('call %s():' % func.__name__)
return func(*args, **kw)
return wrapper
def now():
print('2015-3-25')
now()
# 2015-3-25
# 增加装饰器
@log
def now():
print('2015-3-25')
now()
'''
call now1():
2015-3-25
'''
'''
1. 把@log放到now()函数的定义处,相当于执行了语句:now = log(now)。
由于log()是一个decorator,返回函数wrapper,所以,原来的now()函数仍然存在,只是现在同名的now变量指向了新的函数,于是调用now()将执行新函数,即在log()函数中返回的wrapper()函数。
wrapper()函数的参数定义是(*args, **kw),因此,wrapper()函数可以接受任意参数的调用。在wrapper()函数内,首先打印日志,再紧接着调用原始函数
2. 调用now()函数,不仅会运行now()函数本身,还会在运行now()函数前打印一行日志
'''
# 运行顺序
def log(name=None): #
"""记录函数执行日志"""
print('2')
def decorator(func):
print('4')
def wrapper(*args, **kwargs): # ? 元组 字典 魔法参数
print('6')
print('{0}.start...'.format(name))
a = 1000 # 不会改变 传入函数的值 和被装饰函数的值 各模块之间的独立性
k = 999
print(args) # ()
print(kwargs) # {}
print('7')
rest = func(*args, **kwargs) # 传入 保存返回值
print(a,k)# 不会改变 传入函数的值 和被装饰函数的值 各模块之间的独立性
print('9')
print(rest)
print('10')
print('{0}.end...'.format(name))
print('11')
print('5')
return wrapper
print('3')
return decorator
print('1')
@log('from add')
def add(a, b, *args, **kwargs): # 后面参数的意义
print('8')
a = 10
c = a + b
return c
if __name__ == '__main__':
rest = add(5, 6, 100, k=7, v=8, m=11)
print('12')
print('——————————————————————————')
from functools import wraps
def log(name=None):
""" 记录函数执行的日志 """
def decorator(func):
@wraps(func)
def wrapper2(*args, **kwargs):
""" 装饰器内部的函数 """
print('{0}.start...'.format(name))
print('-----warpper: {0}'.format(func.__name__))
print('-----warpper: {0}'.format(func.__doc__))
rest = func(*args, **kwargs)
print('{0}.end..'.format(name))
return rest
# wrapper2.__doc__ = func.__doc__
# wrapper2.__name__ = func.__name__
return wrapper2
return decorator
# 完整的decorator
@log('hello')
def hello():
""" 简单功能模拟 """
print('hello world')
if __name__ == '__main__':
print('doc: {0}'.format(hello.__doc__))
print('name: {0}'.format(hello.__name__))
hello()
'''
doc: 简单功能模拟
name: hello
hello.start...
-----warpper: hello
-----warpper: 简单功能模拟
hello world
hello.end..
'''
# 多个装饰器 嵌套
def log(fun):
"""纪录函数执行的日志"""
def wrapper():#不改变原功能
print('1')
print('start...')
print('2')
fun()
print('9')
print('end...')
print('10')
return wrapper#?装饰器返回函数不加括号注意返回不要执行
def log_in(func):
"""记录函数执行的日志"""
def wrapper():
print('3')
print('开始进入...')
print('4')
func()
print('7')
print('结束...')
print('8')
return wrapper
@log
@log_in#轮流执行多个装饰器再进入函数
def test():
print('5')
print('test..')
print('6')
if __name__=='__main__':
test()#结果同时执行
借助Python的@语法,把decorator置于函数的定义处
装饰器和被装饰函数的顺序
当装饰器和被装饰函数定义在同一个.py文件时,装饰器需要定义在被装饰函数的前面,python代码是自上而下执行,从而使得程序在执行时可以先调用上面的装饰器
运行顺序如上图
装饰器中 临时保存 传入函数的返回值 ,注意位置
完整的decorator,调用 functools.wraps ,避免了装饰器干扰内置函数
问题:
测试代码中调用 print(‘doc: {0}’.format(hello._doc_)) 、 print(‘name: {0}’.format(hello.__name__)),返回的是装饰器的内置函数.返回的那个wrapper2()函数名字就是’wrapper’,所以,需要把原始函数的name等属性复制到wrapper()函数中,否则,有些依赖函数签名的代码执行就会出错
剖析:
函数也是对象,它有__name__等属性,经过decorator装饰之后的函数,它们的__name__已经从原来的’now’变成了’wrapper’:
解决:
不需要编写wrapper.name = func.__name__这样的代码,Python内置的functools.wraps就是干这个事的,所以,一个完整的decorator的写法如下:
定义多个装饰器,注意执行的顺序。避免传递函数的嵌套造成问题
对象的引用就是赋值的过程。
我们举个栗子:
a = [“a”, “b”, “c”]
b = a
a is b
Out:
True
在上面的栗子里我们把a又重新赋值给 b,那么从 Python 内部机制来看,这个赋值的过程,其实只是又新建了一层引用(这里的引用,类似于指针的概念),建立了从 b 到真实的 list 数据的引用。对 a 进行修改,b 会跟着变化,反之亦然。这就是引用的概念。该过程的原理图如下,用 is 比较 a 和 b 的时候,是比较其共同指向的同一块内存,同一性判断自然为 True。判断2个变量是否具有同一性,还可以用 id() 函数,该方法可以获取对象的内存地址。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4ZtuuRtW-1614984312172)(/Users/wu/Documents/image-20210127163127117.png)]
数字和字符串中的内存都指向同一个地址,所以深拷贝和浅拷贝对于他们而言都是无意义的。也就是说,我们研究深拷贝和浅拷贝,都是针对可变对象进行研究,最常见的情况就是列表
深拷贝
所谓的深拷贝,也就是基于被拷贝的可变对象,建立一个完全一样的拷贝后的对象,二者之间除了长得一模一样,但是相互独立,并不会互相影响。经过深拷贝操作后,拷贝后得到的对象的任何操作均无法改变原始对象。Python的原生拷贝操作需要导入copy包,其中的deepcopy()函数表示深拷贝
浅拷贝
其实既然 Python 的 copy 有深浅之分,那显然浅拷贝必然有不一样的地方。
如果只是针对由不可变的对象组成的单层常规列表,浅拷贝和深拷贝并无任何区别。
嵌套列表
不可变对象组成的列表,浅拷贝和深拷贝效果一样,拷贝前后互相独立,互不影响;
可变元素时,浅拷贝只是建立了一个由该元素指向新列表的引用(指针),当该元素发生变化的时候,拷贝后的对象也会发生变化;
深拷贝完全不考虑节约内存,浅拷贝则相对来讲比较节约内存,浅拷贝仅仅是拷贝第一层元素;
# 深拷贝
import copy
m = ["Jack", "Tom", "Brown"]
n = copy.deepcopy(m)
# 判断二者是否相等,结果显而易见
m == n
Out: True
# 判断二者是否具有同一性,答案为否。也就是说,列表m和列表n是存储在不同的地址里。
m is n
Out: False
# 改变m首位的元素,发现n并无变化,说明二者互不影响
m[0] = "Helen"
m
Out: ['Helen', 'Tom', 'Brown']
n
Out: ['Jack', 'Tom', 'Brown']
# 单层浅拷贝
# 用copy库中的copy方法来表示浅拷贝
import copy
m = ["Jack", "Tom", "Brown"]
n = copy.copy(m)
# 判断浅拷贝前后是否具有同一性,答案是不具备同一性
m is n
Out: False
# 更改m的值,发现n并无任何变化。这里的规律保持和深拷贝一致
m[0] = "Black"
n
Out: ['Jack', 'Tom', 'Brown']
# 嵌套浅拷贝
# students列表的长度为3,其中首位为字符串,其他位均为列表
students = ["Class 1", ["Jack", 178, 120], ["Tom", 174, 109]]
students_c = copy.copy(students)
# 查看内嵌的列表是否具备同一性
students[1] is students_c[1]
Out: True
# 尝试更改students中某位学生的信息,通过测试更改后的students和students_c
students[1][1] = 180
students
Out: ['Class 1', ['Jack', 180, 120], ['Tom', 174, 109]]
students_c
Out: ['Class 1', ['Jack', 180, 120], ['Tom', 174, 109]]
## 发现:students_c也跟着改变了,这说明对于嵌套列表里的可变元素(深层次的数据结构),浅拷贝并没有进行拷贝,只是对其进行了引用
# 我们接着尝试更改students中的班级信息
students[0] = "Class 2"
students
Out: ['Class 2', ['Jack', 180, 120], ['Tom', 174, 109]]
students_c
Out: ['Class 1', ['Jack', 180, 120], ['Tom', 174, 109]]
## 发现:students_c没有发生变化,这说明对于嵌套列表里的不可变元素,浅拷贝和深拷贝效果一样
#切片与浅拷贝
# 我们沿用上面的students列表的数据,通过对students进行切片等一系列微操作
students = ["Class 1", ["Jack", 178, 120], ["Tom", 174, 109]]
students_silce = students[:2]
# 对students的前2项进行切片,并赋值给students_silce;
# 修改students_silce的第二项,修改其中身高值,并比较源列表和切片结果的变化
students_silce[-1][1] = 185
students_silce
Out: ['Class 1', ['Jack', 185, 120]]
students
Out: ['Class 1', ['Jack', 185, 120], ['Tom', 174, 109]]
## 比较发现,切片结果的变化值,也传递给了源列表。说明可变元素的数据结构只是被引用,没有被复制。
# 修改students_silce的第一项,修改班级名,并比较源列表和切片结果的变化
students_silce[0] = "Class 3"
students_silce
Out: ['Class 3', ['Jack', 185, 120]]
students
Out: ['Class 1', ['Jack', 185, 120], ['Tom', 174, 109]]
# 比较发现,切片结果的变化值,没有传递给了源列表。说明对于不可变元素,切片前后互相独立。
## 综合比较,可以发现,切片的效果其实就是浅拷贝!
面向过程 | 面向对象 | |
---|---|---|
定义 | 分析出解决问题的步骤,然后逐步实现。 | 找出解决问题的人,然后分配职责。 |
理解 | 例如:婚礼筹办 – 发请柬(选照片、措词、制作) – 宴席(场地、找厨师、准备桌椅餐具、计划菜品、购买食材) – 婚礼仪式(定婚礼仪式流程、请主持人) | 例如:婚礼筹办 – 发请柬:找摄影公司(拍照片、制作请柬) – 宴席:找酒店(告诉对方标准、数量、挑选菜品) – 婚礼仪式:找婚庆公司(对方提供司仪、制定流程、提供设备、帮助执行) |
公式 | 程序 = 算法 + 数据结构 | 程序 = 对象 + 交互 |
优点 | 所有环节、细节自己掌控。 | 思维:更接近于人的思维方式。 有利于梳理归纳、分析解决问题。 技术上:高复用:对重复的代码进行封装,提高开发效率。高扩展:增加新的功能,不修改以前的代码。高维护:代码可读性好,逻辑清晰,结构规整 |
缺点 | 考虑所有细节,工作量大。 | – 高扩展:增加新的功能,不修改以前的代码。 |
封装、继承、多态
一个抽象的概念,即生活中的”类别”。拥有实例、属性和方法。用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
概念
类与类行为不同,对象与对象数据不同。例如:
学生student是一个类,具有姓名,年龄等数据; 具有学习study,工作work等行为。
对象:悟空同学,28岁
八戒同学,29岁。
车 car是一个类,具有类型type,速度speed等数据;启动start,停止stop,行驶run等行为。
对象:宝马,180.
比亚迪,100.
狗dog是一个类,具有类型,姓名,重量weight等数据,拉臭臭shit,玩play等行为。
对象:拉布拉多,米咻。 金毛,
设计原则
开-闭原则(目标、总的指导思想)
Open Closed Principle
对扩展开放,对修改关闭。
增加新功能,不改变原有代码。
类的单一职责(一个类的定义)
Single Responsibility Principle
一个类有且只有一个改变它的原因。
依赖倒置(依赖抽象)
Dependency Inversion Principle
客户端代码(调用的类)尽量依赖(使用)抽象的组件。
抽象的是稳定的。实现是多变的。
组合复用原则(复用的最佳实践)
Composite Reuse Principle
如果仅仅为了代码复用优先选择组合复用,而非继承复用。
组合的耦合性相对继承低。
里氏替换(继承后的重写,指导继承的设计)
Liskov Substitution Principle
父类出现的地方可以被子类替换,在替换后依然保持原功能。
子类要拥有父类的所有功能。
子类在重写父类方法时,尽量选择扩展重写,防止改变了功能。
迪米特法则(类与类交互的原则)
Law of Demeter
不要和陌生人说话。
类与类交互时,在满足功能要求的基础上,传递的数据量越少越好。因为这样可能降低耦合度。
class people:
“””文档说明””
#定义基本属性
name = ''
age = 0
#定义私有属性,私有属性在类外部无法直接进行访问
__weight__ = 0
#定义构造方法,方法成员
def __init__(self,n,a,w):
self.name = n
self.age = a
self.__weight = w
def speak(self):
print("%s 说: 我 %d 岁。" %(self.name,self.age))
# 创建类
class 类名 (object):
“””文档说明””
类属性
def _init_(self,参数列表):
self.实例变量 = 参数
类实例化后,可以使用其属性,实际上,创建一个类之后,可以通过类名访问其属性。
方法成员
# 实例变量
对象.变量名
# 实例方法
def 方法名称(self, 参数列表):
方法体
class后面紧接着是类名,类名通常是大写开头的单词,紧接着是(object),表示该类是从哪个类继承下来的,继承的概念我们后面再讲,通常,如果没有合适的继承类,就使用object类,这是所有类最终都会继承的类。
类名所有单词首字母大写.
初始化 :很多类都倾向于将对象创建为有初始状态的。
定义一个名为 _init_() 的特殊方法(构造方法),_init_ 也叫构造函数,创建对象时被调用,也可以省略.
def _init_(self,name,*args*,*kwargs*):
self.name = name
类定义了 __init_方法的话,类的实例化操作会自动调用 _init() 方法。 __init_方法可以有参数,参数通过 _init() 传递到类的实例化操作上。例如:
class Complex:
def init(self, realpart, imagpart):
self.r = realpart
self.i = imagpart
x = Complex(3.0, -4.5)
x.r, x.i
(3.0, -4.5)
#### 实例变量
1. 作用 :描述所有对象的共有数据。
2. 语法
定义:对象.变量名
调用:对象.变量名
3. 说明 :
1. 首次通过对象赋值为创建,再次赋值为修改.
w01 = Wife()
w01.name = “丽丽”
w01.name = “莉莉”
2. 通常在构造函数(_init_)中创建。
每个对象存储一份,通过对象地址访问。
3. \__dict__:
对象的属性,用于存储自身实例变量的字典。
#### 实例方法
1. 作用:表示对象行为
在类地内部,使用def关键字可以为类定义一个方法,与一般函数定义不同,类方法必须包含参数self,且为第一个参数类的私有方法
2. 语法
定义:
def 方法名称(self, 参数列表)
方法体
调用:
对象地址.实例方法名(参数列表)
3. 案例
```python
#!/usr/bin/python3
class JustCounter:
__secretCount = 0 # 私有变量
publicCount = 0 # 公开变量
def count(self):
self.__secretCount += 1
self.publicCount += 1
print (self.__secretCount)
counter = JustCounter()
counter.count()
counter.count()
print (counter.publicCount)
print (counter.__secretCount) # 报错,实例不能访问私有变量
’‘’
执行以上程序输出结果为:
1
2
2
Traceback (most recent call last):
File "test.py", line 16, in
print (counter.__secretCount) # 报错,实例不能访问私有变量
AttributeError: 'JustCounter' object has no attribute '__secretCount
‘’‘
说明
不建议通过类名访问实例方法
至少有一个形参,第一个参数绑定调用这个方法的对象,一般命名为"self"。
self 变量绑定的是被创建的对象,名称可以随意
创建多少对象,方法只有一份,并且被所有对象共享。
对象:
通过类定义的数据结构 进行实例,是一个相对概念,即归属于某个类别的”个体”。子定义函数时,self代表的就是对象。对象包括两个数据成员(类变量和实例变量)和方法。。
属性 :对象具有的静态特征
方法:对象具有的动态特征。类中定义的函数
类对象支持两种操作:属性引用和实例化。
实例化
变量 = 构造函数 (参数列表)
属性引用:
使用和 Python 中所有的属性引用一样的标准语法:obj.name。类对象创建后,类命名空间中所有的命名都是有效属性名。
案例:
class MyClass:
"""一个简单的类实例"""
i = 12345
def f(self):
return 'hello world'
# 实例化类
x = MyClass()
# 访问类的属性和方法
print("MyClass 类的属性 i 为:", x.i)
print("MyClass 类的方法 f 输出为:", x.f())
# 执行以上程序输出结果为:
MyClass 类的属性 i 为: 12345
MyClass 类的方法 f 输出为: hello world
隐藏对象的信息,留出访问接口。隐藏实现的细节,将类的某些信息隐藏在类的内部,不允许外部程序访问。通过该类的提供的方法来实现对隐藏信息的操作和访问。通过规定的方法访问数据,向类外提供功能。数据角度讲,将一些基本数据类型复合成一个自定义类型。
分而治之
将一个大的需求分解为许多类,每个类处理一个独立的功能。
拆分好处:便于分工,便于复用,可扩展性强。
封装变化
变化的地方独立封装,避免影响其他类。
高内 聚
类中各个方法都在完成一项任务(单一职责的类)
低 耦 合
类与类的关联性与依赖度要低(每个类独立),让一个类的改变,尽少影响其他类。
最高的内聚莫过于类中仅包含1个方法,将会导致高内聚高耦合。
最低的耦合莫过于类中包含所有方法,将会导致低耦合低内聚。
作用
无需向类外提供的成员,可以通过私有化进行屏蔽。
做法
两个下划线开头,声明该属性为私有,不能在类地外部被使用或直接访问。在类内部的方法中使用时self.__private_attrs。可以通过内部的函数操作。
本质
障眼法,实际也可以访问。
私有成员的名称被修改为:_类名__成员名,可以通过_dict_属性或dir函数查看。
类的内置方法
class Vector:
def __init__(self, a, b):
self.a = a
self.b = b
def __str__(self):
return 'Vector (%d, %d)' % (self.a, self.b)
def __add__(self,othe):
return Vector(self.a + othe.a, self.b + othe.b)
v1 = Vector(2,10)
v2 = Vector(5,-2)
v3 = Vector(-7,-8)
print(v1)
print(v2)
print (v1 + v2+v3)
'''
Vector (2, 10)
Vector (5, -2)
Vector (0, 0)
'''
_init_ 初始化变量: 构造函数,创建对象后,就立刻被默认调用了,可接收参数
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WLql1FJf-1614984312173)(/Users/wu/Documents/image-20210131224621006.png)]
_str_:返回值为一个字符串对象
和内置函数str实际上实现的是同一功能,
使用
由于object类定义了__str__方法,因此所有类都会继承该方法,除非有自定义类重写了该方法。什么情况下会触发__str__方法呢?主要有如下情况会触发__str__的调用:
在交互环境下直接输入str(对象名)查看对象内容;
print(对象)查看对象内容时
直接调用“对象.str()”方法;
由于列表以及字典等容器总是会使用 repr 方法,即使调用__str__方法访问输出的还是__repr__访问内容。
# __str__
#打印时触发
class A:
def __str__(self):
#打印时执行这行代码
return ’ok‘
print(A()) #相当于print(A().__str__())
_slots_
作用:限制类的属性.限定一个类创建的实例只能有固定的实例变量,不能再额外添加。、
语法:在类中定义 _slots_ = (“变量名1”,”变量名2”……)
说明: 含有__slots__属性的类所创建的对象没有__dict__属性, 即此实例不用字典来存储对象的实例属性。
优点:访止用户因错写属性的名称而发生程序错误。
缺点:丧失了动态语言可以在运行时为对象添加变量的灵活性。
__new__
new至少要有一个参数cls,代表当前类,此参数在实例化时由 Python解释器自动识别
new必须要有返回值,返回实例化出来的实例,这点在自己实现new时要特别注意,可以 return父类(通过 super(当前类名,cs))neW出来的实例,或者直接是 object的neW出来的实例
init有一个参数sef,就是这个new返回的实例,init在neW的基础上可以完成一些其它初始化的动作,init不需要返回值
如果new创建的是当前类的实例,会自动调用init函数,通过 return语句里面调用的new函数的第一个参数是cls来保证是当前类实例,如果是其他类的类名,那么实际创建返回的就是其他类的实例,其实就不会调用当前类的init函数,也不会调用其他类的init函数
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EoK0IkAO-1614984312174)(/Users/wu/Documents/image-20210131225637306.png)]
_del_ : 析构函数,释放对象时使用_
_repr : 打印,转换_
_next_ 迭代函数规则
_iter_ 生成迭代器
_len_: 获得长度_
_cmp: 比较运算__
_call_: 函数调用_
_add_: 加运算_
……
静态方法 /属性@property
定义常用的工具函数。
公开的实例变量,缺少逻辑验证。私有的实例变量与两个公开的方法相结合,又使调用者的操作略显复杂。而属性可以将两个方法的使用方式像操作变量一样方便
定义:
@staticmethod
def 方法名称(参数列表):
# 方法体
# 案例:
@property
def name(self):
return self.__name
@name.setter
def name(self, name):
self.__name = name
(使用@ staticmethod修饰的目的是该方法不需要隐式传参数。静态方法不能访问实例成员和类成员)
调用:
对象.属性名 = 数据
变量 = 对象.属性名
不建议通过对象访问静态方法
说明:
– 通常两个公开的属性,保护一个私有的变量。
– @property 负责读取,@属性名.setter 负责写入
– 只写:属性名= property(None, 写入方法名)
类与类之间的关系,抽取类与类之间的公共属性,建立夫类。重复利用父类,建立子类。重用现有类的功能与概念,并在此基础上进行建立新类。事物具有一定的层次、渊源,继承可以统一概念。
相关概念
父类(基类、超类)、子类(派生类)。
父类相对于子类更抽象,范围更宽泛;子类相对于父类更具体,范围更狭小。
单继承:父类只有一个(
多继承:父类有多个
Object类:任何类都直接或间接继承自 object 类
作用
隔离客户端代码与功能的实现方式。
适用于:多个类在概念上是一致的,且需要进行统一的处理
优点
一种代码复用的方式。
以层次化的方式管理类。
缺点
耦合度高
# 单继承
class DerivedClassName(BaseClassName1):
<statement-1>
.
.
.
<statement-N>
# 多继承
class DerivedClassName(Base1, Base2, Base3):
<statement-1>
.
.
.
<statement-N>
# 单继承 案例
class Parent: # 定义父类
def myMethod(self):
print ('调用父类方法')
#继承父类的方法
class Child(Parent): # 定义子类
def myMethod(self):
# 重写方法
print ('调用子类方法')
?Super(Child,self).myMethod
# 子类实例
c = Child()
# 子类调用重写方法
c.myMethod()
’‘’
执行以上程序输出结果为:
调用子类方法
‘’‘
# 单继承
class people:
#定义基本属性
name = ''
age = 0
#定义私有属性,私有属性在类外部无法直接进行访问
__weight = 0
#定义构造方法
def __init__(self,n,a,w):
self.name = n
self.age = a
self.__weight = w
def speak(self):
print("%s 说: 我 %d 岁。" %(self.name,self.age)
class student(people):
grade = ''
def __init__(self,n,a,w,g):
#调用父类的构函
people.__init__(self,n,a,w)
self.grade = g
#覆写父类的方法
def speak(self):
print("%s 说: 我 %d 岁了,我在读 %d 年级"%(self.name,self.age,self.grade))
s = student('ken',10,60,3)
s.speak()
'''
执行以上程序输出结果为:
ken 说: 我 10 岁了,我在读 3 年级
'''
#另一个父类,多重继承之前的准备
class speaker():
topic = ''
name = ''
def __init__(self,n,t):
self.name = n
self.topic = t
def speak(self):
print("我叫 %s,我是一个演说家,我演讲的主题是 %s"%(self.name,self.topic))
#多重继承
class sample(speaker,student):
a =''
def __init__(self,n,a,w,g,t):
student.__init__(self,n,a,w,g)
speaker.__init__(self,n,t)
test = sample("Tim",25,80,4,"Python")
#方法名同,默认调用的是在括号中排前地父类的方法
test.speak()
’‘’
执行以上程序输出结果为:
我
’‘’
BaseClassName(示例中的基类名)
必须与派生类定义在一个作用域内。除了类,还可以用表达式,基类定义在另一个模块中时这一点非常有用:class DerivedClassName(modname.BaseClassNam
同名方法的解析顺序(MRO, Method Resolution Order):
类自身 --> 父类继承列表(由左至右)–> 再上层父类
括号中基类的顺序,若是基类中有相同的方法名,而在子类使用时未指定,python从左至右搜索 即方法在子类中未找到时,从左到右查找基类中是否包含方法。
子类(派生类)必须拥有父类(基类)全部属性,可以新增。
即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。
继承的连续
子类的子类,依然是子类
方法重写
如果你的父类方法的功能不能满足你的需求,你可以在子类重写你父类的方法,
?内置函数
isinstance(obj, class_or_tuple)
返回这个对象obj 是否是某个类的对象,或者某些类中的一个类的对象。
单继承
只有一个父类
多继承
一个子类继承两个或两个以上的基类,父类中的属性和方法同时被子类继承下来。
父类的同一种动作或者行为,在不同的子类上有不同的实现。
子类对同一信息,有不同的响应
必须满足继承关系,并且对子类有方法的重写。
作用
继承将相关概念的共性进行抽象,多态在共性的基础上,体现类型的个性化(一个行为有不同的实现)。增强程序扩展性,体现开闭原则。
重写
子类实现了父类中相同的方法(方法名、参数),在调用该方法时,实际调用的是子类的方法。
增 | ||
---|---|---|
递归文件夹创建函数。像mkdir(), 但创建的所有intermediate-level文件夹需要包含子文件夹 | [os.makedirs(path, mode]) | |
以数字mode的mode创建一个名为path的文件夹.默认的 mode 是 0777 (八进制)。 | [os.mkdir(path, mode]) | |
删 | 删除一个文件 | os.remove |
查 | ||
切换到目标路径 | os.chdir(path) | |
字符串指示正在使用的平台 | os.name) | |
返回当前工作目录 | os.getcwd() | |
返回path包含的文件或文件夹的名字的列表。 | os.listdir(path) | |
路径 | [Os.path](file:///Library/Frameworks/Python.framework/Versions/3.7/Resources/English.lproj/Documentation/library/os.path.html?highlight=os path#module-os.path) | |
返回路径的目录名和文件名 | os.path.split | |
检验给出的路径是否真地存在 | os.path.exists | |
判断类型 | Isfile | |
路径名的目录部分 | Dirname | |
返回文件后缀 | Splitext | |
对path进行拼接 | Join 类似os.sep | |
获得文件名 | Basenam | |
获取完整路径 | abspath | |
改 | ||
切换到目标路径 | os.chdir(path) | |
重命名文件或目录 | os.rename(src, dst) | |
os.system | ||
获得运行的环境信息 | os.environ | |
os.sep |
# os.environ
#查询路径
print(os.environ['PATH'])
# 当前用户
print(os.environ['USER'])
# 根目录
print(os.environ['HOME'])
# os.chdir
os.chdir('/Users/wu/Desktop')
# 相对路径和绝对路径
os.chdir('C:\\Users\\Hjx\\Desktop\\' )
f2 = open('text.txt','r')
print(f2.read())
# 在申明了目录之后,就可以直接输出文件名了 → 相对路径
os.listdir()
os.path.splitext('/Users/wu/Desktop/jinping.xmind')
os.path.isfile('xaiowu')
import sys
sys.path
查看Python的搜索路径,输出是一个列表,其中第一项是空串’’,代表当前目录(若是从一个脚本中打印出来的话,可以更清楚地看出是哪个目录),亦即我们执行python解释器的目录(对于脚本的话就是运行的脚本所在的目录)
添加sys.path.append(“c:\”)
将自定义模块的路径添加到系统的环境变量(sys.path)
re模块
主要定义了9个常量、12个函数、1个异常,
re模块官方文档:https://docs.python.org/zh-cn/3/library/re.html
re模块库源码:https://github.com/python/cpython/blob/3.8/Lib/re.py
正则表达式
(regular expression)描述了一种字符串匹配的模式(pattern),是用于处理字符串,匹配字符串.
模式描述在搜索文本时要匹配的一个或多个字符串。
正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配.
设计思想
用一种描述性的语言(特定的符号)来给字符串定义一个规则,凡是符合规则的字符串,我们就认为它“匹配”了,否则,该字符串就是不合法的。
构造正则表达式的方法和创建数学表达式的方法一样。用多种元字符与运算符可以将小的表达式结合在一起来创建更大的表达式。
组件:单个的字符、字符集合、字符范围、字符间的选择或者所有这些组件的任意组合。
普通字符、非打印字符
为什么使用正则表达式?
典型的搜索和替换操作对于对静态文本执行可能已经足够了,但若采用这种方法搜索动态文本,即使不是不可能,至少也会变得很困难。通过使用正则表达式,可以:
测试字符串内的模式。
例如,可以测试输入字符串,以查看字符串内是否出现电话号码模式或信用卡号码模式。这称为数据验证。
替换文本。
可以使用正则表达式来识别文档中的特定文本,完全删除该文本或者用其他文本替换它。
基于模式匹配从字符串中提取子字符串。
可以查找文档内或输入域内特定的文本
组件:单个的字符、字符集合、字符范围、字符间的选择或者所有这些组件的任意组合。
普通字符、非打印字符
普通字符包括没有显式指定为元字符的所有可打印和不可打印字符。这包括所有大写和小写字母、所有数字、所有标点符号和一些其他符号。
非打印字符也可以是正则表达式的组成部分。下表列出了表示非打印字符的转义序列:
字符 | 描述 |
---|---|
\cx | 匹配由x指明的控制字符。例如, \cM 匹配一个 Control-M 或回车符。x 的值必须为 A-Z 或 a-z 之一。否则,将 c 视为一个原义的 ‘c’ 字符。 |
\f | 匹配一个换页符。等价于 \x0c 和 \cL。 |
\n | 匹配一个换行符。等价于 \x0a 和 \cJ。 |
\r | 匹配一个回车符。等价于 \x0d 和 \cM。 |
\s | 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。注意 Unicode 正则表达式会匹配全角空格符。 |
\S | 匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。 |
\t | 匹配一个制表符。等价于 \x09 和 \cI。 |
\v | 匹配一个垂直制表符。等价于 \x0b 和 \cK。 |
\xn | 匹配 n,其中 n 为十六进制转义值。十六进制转义值必须为确定的两个数字长。例如,’\x41’ 匹配 “A”。’\x041’ 则等价于 ‘\x04’ & “1”。正则表达式中可以使用 ASCII 编码。 |
\num | 匹配 num,其中 num 是一个正整数。对所获取的匹配的引用。例如,’(.)\1’ 匹配两个连续的相同字符。 |
\n | 标识一个八进制转义值或一个向后引用。如果 \n 之前至少 n 个获取的子表达式,则 n 为向后引用。否则,如果 n 为八进制数字 (0-7),则 n 为一个八进制转义值。 |
\nm | 标识一个八进制转义值或一个向后引用。如果 \nm 之前至少有 nm 个获得子表达式,则 nm 为向后引用。如果 \nm 之前至少有 n 个获取,则 n 为一个后跟文字 m 的向后引用。如果前面的条件都不满足,若 n 和 m 均为八进制数字 (0-7),则 \nm 将匹配八进制转义值 nm。 |
\nml | 如果 n 为八进制数字 (0-3),且 m 和 l 均为八进制数字 (0-7),则匹配八进制转义值 nml。 |
\un | 匹配 n,其中 n 是一个用四个十六进制数字表示的 Unicode 字符。例如, \u00A9 匹配版权符号 (?)。 [\u4e00-\u9fa5] |
可以写在字符集中
\d | 匹配一个数字字符。等价于 [0-9]。 |
---|---|
\D | 匹配一个非数字字符。等价于 [^0-9]。 |
\s | 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。 |
\S | 匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。 |
\w | 匹配字母、数字、下划线。等价于’[A-Za-z0-9_]’。 |
\W | 匹配非字母、数字、下划线。等价于 ‘[^A-Za-z0-9_]’。 |
所谓特殊字符,就是一些有特殊含义的字符,简单的说就是表示任何字符串的意思。如果要查找字符串中的 ***** 符号,则需要对 ***** 进行转义,即在其前加一个 ***: runo*ob 匹配 runoob。
许多元字符要求在试图匹配它们时特别对待。若要匹配这些特殊字符,必须首先使字符"转义",即,将反斜杠字符**** 放在它们前面。下表列出了正则表达式中的特殊字符:
特别字符 | 描述 |
---|---|
. | 匹配除换行符 \n 之外的任何单字符。要匹配 . ,请使用 . 。 在DOTALL模式中也能匹配换行符 |
\ | 转义符:将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制。例如, ‘n’ 匹配字符 ‘n’。’\n’ 匹配换行符。序列 ‘\’ 匹配 “”,而 ‘(’ 则匹配 “(”。 |
[xyz] | 用于表示一个字符集合。在一个集合中: 单独列出:比如 [amk] 匹配 ‘a’, ‘m’, 或者 ‘k’。 字符范围,通过用 ‘-’ 将两个字符连起来。比如 [a-z] 将匹配任何小写ASCII字符, [0-5][0-9] 将匹配从 00 到 59 的两位数字, [0-9A-Fa-f] 将匹配任何十六进制数位。 - 进行了转义 (比如 [a-z])或者它的位置在首位或者末尾(如 [-a] 或 [a-]),它就只表示普通字符 ‘-’。 特殊字符在集合中,失去它的特殊含义。比如 [(+)] 只会匹配这几个文法字符 ‘(’, ‘+’, '’, or ‘)’。 字符类如 \w 或者 \S (如下定义) 在集合内可以接受,它们可以匹配的字符由 ASCII 或者 LOCALE 模式决定。 不在集合范围内的字符可以通过 取反 来进行匹配。如果集合首字符是 ‘^’ ,所有 不 在集合内的字符将会被匹配,比如 [^5] 将匹配所有字符,除了 ‘5’, [^^] 将匹配所有字符,除了 ‘^’. ^ 如果不在集合首位,就没有特殊含义。 在集合内要匹配一个字符 ‘]’,有两种方法,要么就在它之前加上反斜杠,要么就把它放到集合首位。比如, [()[]{}] 和 [{}] 都可以匹配括号。 Unicode Technical Standard #18 里的嵌套集合和集合操作支持可能在未来添加。这将会改变语法,所以为了帮助这个改变,一个 FutureWarning 将会在有多义的情况里被 raise,包含以下几种情况,集合由 ‘[’ 开始,或者包含下列字符序列 ‘–’, ‘&&’, ‘~~’, 和 ‘||’。为了避免警告,需要将它们用反斜杠转义。 在 3.7 版更改* 如果一个字符串构建的语义在未来会改变的话,一个 FutureWarning 会 raise 。 |
( ) | 标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。要匹配这些字符,请使用 ( 和 )。 |
[ | 标记一个中括号表达式的开始。要匹配 [,请使用 [。 |
? | 匹配前面的子表达式零次或一次,或指明一个非贪婪限定符。要匹配 ? 字符,请使用 ?。 |
^ | 匹配输入字符串的开始位置,除非在方括号表达式中使用,当该符号在方括号表达式中使用时,表示不接受该方括号表达式中的字符集合。要匹配 ^ 字符本身,请使用 ^。 |
{ | 标记限定符表达式的开始。要匹配 {,请使用 {。 |
定位符使您能够将正则表达式固定到行首或行尾。它们还使您能够创建这样的正则表达式,这些正则表达式出现在一个单词内、在一个单词的开头或者一个单词的结尾。定位符用来描述字符串或单词的边界,^ 和 $ 分别指字符串的开始与结束,\b 描述单词的前或后边界,\B 表示非单词边界。正则表达式的定位符有:
字符 | 描述 |
---|---|
^ | 匹配输入字符串开始的位置。如果设置了 RegExp 对象的 Multiline 属性,^ 还会与 \n 或 \r 之后的位置匹配。 在多行模式中匹配每一行的开头 |
$ | 匹配输入字符串结尾的位置。如果设置了 RegExp 对象的 Multiline 属性,$ 还会与 \n 或 \r 之前的位置匹配。 在多行模式中匹配每一行的末尾 |
\b | 匹配空字符串,但只在单词开始或结尾的位置。一个单词被定义为一个单词字符的序列。注意,通常 \b 定义为 \w 和 \W 字符之间,或者 \w 和字符串开始/结尾的边界, 意思就是 r’\bfoo\b’ 匹配 ‘foo’, ‘foo.’, ‘(foo)’, ‘bar foo baz’ 但不匹配 ‘foobar’ 或者 ‘foo3’。 默认情况下,Unicode字母和数字是在Unicode样式中使用的,但是可以用 ASCII 标记来更改。如果 LOCALE 标记被设置的话,词的边界是由当前语言区域设置决定的,\b 表示退格字符,以便与Python字符串文本兼容。 |
\B | 匹配空字符串,但 不 能在词的开头或者结尾。意思就是 r’py\B’ 匹配 ‘python’, ‘py3’, ‘py2’, 但不匹配 ‘py’, ‘py.’, 或者 ‘py!’. \B 是 \b 的取非,所以Unicode样式的词语是由Unicode字母,数字或下划线构成的,虽然可以用 ASCII 标志来改变。如果使用了 LOCALE 标志,则词的边界由当前语言区域设置。 |
\A | 只匹配字符串开始 |
\Z | 只匹配字符串尾 |
注意:不能将限定符与定位符一起使用。由于在紧靠换行或者单词边界的前面或后面不能有一个以上位置,因此不允许诸如 ^* 之类的表达式。
若要匹配一行文本开始处的文本,请在正则表达式的开始使用 ^ 字符。不要将 ^ 的这种用法与中括号表达式内的用法混淆。
若要匹配一行文本的结束处的文本,请在正则表达式的结束处使用 $ 字符。
限定符用来指定正则表达式的一个给定组件必须要出现多少次才能满足匹配。有 ***** 或 + 或 ? 或 {n} 或 {n,} 或 {n,m} 共6种。
正则表达式的限定符有:
字符 | 描述 |
---|---|
* | 匹配前面的子表达式零次或多次。例如,zo* 能匹配 “z” 以及 “zoo”。* 等价于{0,}。 |
+ | 匹配前面的子表达式一次或多次。例如,‘zo+’ 能匹配 “zo” 以及 “zoo”,但不能匹配 “z”。+ 等价于 {1,}。 |
? | 匹配前面的子表达式零次或一次。例如,“do(es)?” 可以匹配 “do” 、 “does” 中的 “does” 、 “doxy” 中的 “do” 。? 等价于 {0,1}。 |
{n} | n 是一个非负整数。匹配确定的 n 次。例如,‘o{2}’ 不能匹配 “Bob” 中的 ‘o’,但是能匹配 “food” 中的两个 o。 |
{n,} | n 是一个非负整数。至少匹配n 次。例如,‘o{2,}’ 不能匹配 “Bob” 中的 ‘o’,但能匹配 “foooood” 中的所有 o。‘o{1,}’ 等价于 ‘o+’。‘o{0,}’ 则等价于 ‘o*’。 |
{n,m} | m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。例如,“o{1,3}” 将匹配 “fooooood” 中的前三个 o。‘o{0,1}’ 等价于 ‘o?’。请注意在逗号和两个数之间不能有空格。 |
限定数量符? | 限定数量符后面添加?,进入非贪婪模式 |
用圆括号()将所有选择项括起来,相邻的选择项之间用|分隔。但用圆括号会有一个副作用,使相关的匹配会被缓存,此时可用?:放在第一个选项前来消除这种副作用。
其中 ?: 是非捕获元之一,还有两个非捕获元是 ?= 和 ?!,这两个还有更多的含义,前者为正向预查,在任何开始匹配圆括号内的正则表达式模式的位置来匹配搜索字符串,后者为负向预查,在任何开始不匹配该正则表达式模式的位置来匹配搜索字符串。
| | 指明两项之间的一个选择。要匹配 |,请使用 |。 |
---|---|
(…) | 被扩起来作为分组,从表达式左边开始每遇到一个分组的左括号,编号+1 另外分组的表达式作为一个整体,后面可以连接数量词,表达式中的|仅在括号中有作用 (组合),匹配括号内的任意正则表达式,并标识出组合的开始和结尾。匹配完成后,组合的内容可以被获取,并可以在之后用 \number 转义序列进行再次匹配,之后进行详细说明。要匹配字符 ‘(’ 或者 ‘)’, 用 ( 或 ), 或者把它们包含在字符集合里: [(], [)]. |
(?P…) | (命名组合)类似正则组合,但是匹配到的子串组在外部是通过定义的 name 来获取的。组合名必须是有效的Python标识符,并且每个组合名只能用一个正则表达式定义,只能定义一次。一个符号组合同样是一个数字组合,就像这个组合没有被命名一样。 命名组合可以在三种上下文中引用。如果样式是 (?P[’"]).*?(?P=quote) (也就是说,匹配单引号或者双引号括起来的字符串): 引用组合 “quote” 的上下文 引用方法 在正则式自身内 (?P=quote) (如示) \1 处理匹配对象 m m.group(‘quote’) m.end(‘quote’) (等) 传递到 re.sub() 里的 repl 参数中 \g \g<1> \1 |
引用编号为的分组匹配到的字符串 | |
(?P=name) | 引用别名为的分组匹配到的字符串 |
不作为分组
(?…) | 这是个扩展标记法 (一个 ‘?’ 跟随 ‘(’ 并无含义)。 ‘?’ 后面的第一个字符决定了这个构建采用什么样的语法。这种扩展通常并不创建新的组合; (?P…) 是唯一的例外。 以下是目前支持的扩展。 |
---|---|
(?aiLmsux) | ( ‘a’, ‘i’, ‘L’, ‘m’, ‘s’, ‘u’, ‘x’ 中的一个或多个) 这个组合匹配一个空字符串;这些字符对正则表达式设置以下标记 re.A (只匹配ASCII字符), re.I (忽略大小写), re.L (语言依赖), re.M (多行模式), re.S (点dot匹配全部字符), re.U (Unicode匹配), and re.X (冗长模式)。 (这些标记在 模块内容 中描述) 如果你想将这些标记包含在正则表达式中,这个方法就很有用,免去了在 re.compile() 中传递 flag 参数。标记应该在表达式字符串首位表示。 |
(?:pattern) | 匹配 pattern 但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。这在使用 “或” 字符 (|) 来组合一个模式的各个部分是很有用。例如, 'industr(?:y|ies) 就是一个比 ‘industry|industries’ 更简略的表达式。 |
(?#…) | #后面的注释,里面的内容会被忽略。 |
(?=pattern) | 正向肯定预查(look ahead positive assert),在任何匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如,“Windows(?=95|98|NT|2000)“能匹配"Windows2000"中的"Windows”,但不能匹配"Windows3.1"中的"Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。 |
(?!pattern) | 正向否定预查(negative assert),在任何不匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如"Windows(?!95|98|NT|2000)“能匹配"Windows3.1"中的"Windows”,但不能匹配"Windows2000"中的"Windows"。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。 |
(?<=pattern) | 反向(look behind)肯定预查,与正向肯定预查类似,只是方向相反。例如,"(?<=95|98|NT|2000)Windows"能匹配"2000Windows"中的"Windows",但不能匹配"3.1Windows"中的"Windows"。 |
(? | 反向否定预查,与正向否定预查类似,只是方向相反。例如"(? |
[\u4e00-\u9fa5] | python正则匹配汉字的规则为 |
IGNORECASE
语法: re.IGNORECASE 或简写为 re.I
作用: 进行忽略大小写匹配,在默认匹配模式下大写字母B无法匹配小写字母b,而在 忽略大小写 模式下是可以的。代码案例
ASCII
语法: re.ASCII 或简写为 re.A
作用: 顾名思义,ASCII表示ASCII码的意思,让 \w, \W, \b, \B, \d, \D, \s 和 \S 只匹配ASCII,而不是Unicode。
代码案例:
DOTALL
语法: re.DOTALL 或简写为 re.S
作用: DOT表示.,ALL表示所有,连起来就是.匹配所有,包括换行符\n。
代码案例:
MULTILINE
语法: re.MULTILINE 或简写为 re.M
作用:多行模式,当某字符串中有换行符\n,默认模式下是不支持换行符特性的,比如:行开头 和 行结尾,而多行模式下是支持匹配行开头的。
代码案例
VERBOSE
**语法:**re.VERBOSE 或简写为 re.X
**作用:**详细模式,可以在正则表达式中加注解!
代码案例:
OCALE
语法: re.LOCALE 或简写为 re.L
作用:** 由当前语言区域决定 \w, \W, \b, \B 和大小写敏感匹配,这个标记只能对byte样式有效。这个标记官方已经不推荐使用,因为语言区域机制很不可靠,它一次只能处理一个 “习惯”,而且只对8位字节有效。注意: 由于这个标记官方已经不推荐使用,而且我也没使用过,所以就不给出实际的案例!
UNICODE
语法: re.UNICODE 或简写为 re.U作用: 与 ASCII 模式类似,匹配unicode编码支持的字符,但是 Python 3 默认字符串已经是Unicode,所以有点冗余。
** DEBUG**
语法: re.DEBUG
作用: 显示编译时的debug信息。
虽然debug模式下确实会打印编译信息,但我并不理解这是什么语言 以及表达的含义,希望了解的朋友能不吝赐教。
代码案例:
EMPLATE
语法: re.TEMPLATE 或简写为 re.T作用: 我也没搞懂TEMPLATE的具体用处,
查找 一个匹配项 返回的都是一个匹配对象(Match)
search
查找任意位置的匹配项。只要有符合正则表达式的字符串就匹配成功
match
必须从字符串开头匹配
fullmatch
整个字符串与正则完全匹配
查找多个匹配项
两个方法基本类似,只不过一个是返回列表,一个是返回迭代器。我们知道列表是一次性生成在内存中,而迭代器是需要使用时一点一点生成出来的,内存使用更优。如果可能存在大量的匹配项的话,建议使用finditer函数,一般情况使用findall函数基本没啥影响
分割
split 用正则表达式将某字符串分割成多段
re.split(pattern, string, maxsplit=0, flags=0) 函数:用 pattern 分开 string , maxsplit表示最多进行分割次数, flags表示模式,就是常量!
与 str.split比较
str.split函数功能简单,不支持正则分割,而re.split支持正则。二者的速度结论是:在 不需要正则支持 且 数据量和数次不多 的情况下使用str.split函数更合适,反之则使用re.split函数
替换
sub
替换掉某字符串中被正则表达式匹配的字符,返回替换后的字符串
re.sub**(pattern, repl, string, count=0, flags=0)**
函数参数讲解:
repl替换掉string中被pattern匹配的字符
repl替换内容既可以是字符串,也可以是一个函数哦! 如果repl为函数时,只能有一个入参:Match匹配对象。
count表示最大替换次数
flags表示正则表达式的常量。值得注意的是:sub函数中的入参:
subn
编译正则对象
compile函数 与 template函数 将正则表达式的样式编译为一个 正则表达式对象 (正则对象Pattern),这个对象与re模块有同样的正则函数(后面我们会讲解Pattern正则对象)。
.其他
escape
可以转义正则表达式中具有特殊含义的字符,比如:,或者
purge
函数作用就是清除正则表达式缓存
数量词的贪婪模式与非贪婪模式
Python里数量词默认是贪婪的(在少数语言里也可能是默认非贪婪),总是尝试匹配尽可能长的字符;
非贪婪的则相反,总是尝试匹配尽可能少的字符。
例如:
***** 和 + 限定符都是贪婪的,因为它们会尽可能多的匹配文字,只有在它们的后面加上一个 ? **就可以实现非贪婪或最小匹配。*例如:
正则表达式"ab*“如果用于查找"abbbc”,将找到"abbb"。而如果使用非贪婪的数量词"ab*?",将找到"a"。
.r 的作用:反斜杠的困扰
与大多数编程语言相同,正则表达式里使用"“作为转义字符,这就可能造成反斜杠困扰。假如你需要匹配文本中的字符”\",那么使用编程语言表示的正则表达式里将需要4个反斜杠"\\\\前两个和后两个分别用于在编程语言里转义成反斜杠,转换成两个反斜杠后再在正则表达式里转义成一个反斜杠。
Python里的原生字符串可以使用r"\“表示。同样,匹配一个数字的”[\d](file:///d)“可以写成r”\d"。有了原生字符串,你再也不用担心是不是漏写了反斜杠,写出来的表达式也更直观。
匹配模式
正则表达式提供了一些可用的匹配模式,比如忽略大小写、多行匹配等,这部分内容将在Pattern类的工厂方法re.compile(pattern[, flags])中一起介绍。
异常
re模块还包含了一个正则表达式的编译错误,当我们给出的正则表达式是一个无效的表达式(就是表达式本身有问题)时,就会raise一个异常!
正则查找函数 返回匹配对象
查找一个匹配项(search、match、fullmatch)的函数返回值都是一个 匹配对象Match ,需要通过match.group() 获取匹配值,这个很容易忘记。
函数介绍
自定义日期和时间 | datetime.datetime() |
---|---|
date | |
time | |
获取当前的时间和日期 | datetime.now() datetime.today() |
字符串转换datetime对象 | datetime.strptime() |
datetime****对象转换成字符串 | strftime |
加减操作,timedelta-时差 | timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0) 得到的结果类型就是timedelta |
代码演示
# 与字符串 互相转化
b1='2012T12/3/12:13v14'
print(datetime.strptime(b1,'%YT%m/%d/%H:%Mv%S').time())
'''12:13:14'''
from datetime import datetime
print(datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
# 1.
from datetime import datetime,time,date,timedelta
print('#datetime模块')
help(datetime)
print(dir(datetime))
print('1.自定义日期和时间')
a=datetime(1995,5,12,23,23,23,90)
'b=datetime(1995,20,23)'#报错
a1=date(2000,12,12)
a2=time(12,12,12,12)
print(a,a1,a2)
'''
1995-05-12 23:23:23.000090 2000-12-12 12:12:12.000012
'''
print('2.获取当前的时间和日期')
print('#time模块')
print(dir(time))
help(time.hour)
print(datetime.now().hour)
print(datetime.now())
print(datetime.now().time())
print(datetime.now().date())
print(datetime.now().year)
print(datetime.now().second)
print(datetime.now().microsecond)
'''
#time模块
['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'dst', 'fold', 'fromisoformat', 'hour', 'isoformat', 'max', 'microsecond', 'min', 'minute', 'replace', 'resolution', 'second', 'strftime', 'tzinfo', 'tzname', 'utcoffset']
Help on getset descriptor datetime.time.hour:
hour
10
2021-01-28 10:58:22.719605
10:58:22.719660
2021-01-28
2021
22
719891
'''
# **字符串转换**datetime对象
b1='2012T12/3/12:13v14'
print(datetime.strptime(b1,'%YT%m/%d/%H:%Mv%S').time())
'''12:13:14'''
# datetime对象转换成字符串
a=datetime.now()
print(a)
b=datetime.strftime(a,'%Y/%m+%d!%H:%M:%S')
print(b)
'''
返回值
2020-05-21 22:17:02.190166
2020/05+21!22:17:02
‘’’
# [time --- 时间的访问和转换](https://docs.python.org/zh-cn/3/library/time.html)
| 推迟调用线程的运行 | [time.sleep](https://www.runoob.com/python/att-time-sleep.html) | 语法: time.sleep(t)
**参数** : t -- 表示进程挂起的秒数。 **返回值** 该函数没有返回值。 |
| ------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |
| | | |
# [random --- 生成伪随机数](https://docs.python.org/zh-cn/3/library/random.html)
### 一、random.random()
生成一个0到1的随机浮点数: 0 <= n < 1.0,没有参数
### 二、random.uniform(a,b)
生成一个指定范围内的随机符点数,两个参数其中一个是上限,一个是下限。如果a > b,则生成的随机数n: a >= n >= b。如果 a = n >= a
### 三、random.randint(a,b)
random.randint(a, b)用于生成一个指定范围内的整数。其中参数a是下限,参数b是上限,生成的随机数n: a <= n <= b
### 四、random.randrange(a,b,s)
random.randrange([start], [stop], step]),从指定范围内,按指定基数递增的集合中获取一个随机数。如:random.randrange(10, 100, 2),结果相当于从[10, 12, 14, 16, … 96, 98]序列中获取一个随机数。random.randrange(10, 100, 2)在结果上与 random.choice(range(10, 100, 2) 等效。
### 五、random.choice()
random.choice从序列中获取一个随机元素。其函数原型为:random.choice(sequence)。参数sequence表示一个有序类型。
这里要说明 一下:sequence在python不是一种特定的类型,而是泛指一系列的类型。list, tuple, 字符串都属于sequence。有关sequence可以查看python手册数据模型这一章。
### 六、random.shuffle()
random.shuffle(sequence)用于将一个列表中的元素打乱。
### 七、random.sample()
random.sample(sequence, k)从指定序列中随机获取指定长度的片断。sample函数不会修改原有序列。
# [collections --- 容器数据类型](https://docs.python.org/zh-cn/3/library/collections.html)
counter(元素计算)
from collections import Counter
a =‘kjalfj;ldsjafl;hdsllfdhg:lahfbl:hl;ahlf;h’
res = Counter(a)
print(res)
# [Numpy](https://numpy.org/devdocs/user/quickstart.html#array-creation)
## 1.简介
1. 优势
| 读写迅速 | Numpy 数组通常是由相同种类的元素组成的,即数组中的数据项的类型一致。这样有一个好处,由于知道数组 元素的类型相同,所以能快速确定存储数据所需空间的大小。 | Python 内置的若干种数据类型,无法高效地应对计算密集型场景,比如矩阵运算。 |
| -------- | ------------------------------------------------------------ | ------------------------------------------------------------ |
| 数组运算 | Numpy 数组能够利用 Numpy 中封装好的函数(矢量化),运用向量化运算来处理整个数组,速度较快; | 而 Python 的列表则通常需要借助循环语句遍历 列表,运行效率相对来说要差。 |
| 高性能 | Numpy 使用了优化过的 C API,运算速度较快。。因为 NumPy 的大部分代码都是用 C 语言写的,其底层算法在设计时就有着极优异的性能,所以使得 NumPy 比纯 Python 代码高效得多 | |
| 开源 | 数据分析中所介绍到几乎所有的高级工具,都是基于 Numpy 开发的 | |
```python
import numpy as np
import time
list_array = list(range(int(1e6))) # 10 的 6次方
start_time = time.time()
python_array = [val * 5 for val in list_array] # 一百万个数字,里面每个数字都乘于 5
end_time = time.time()
print('Python array time: {}ms'.format(round((end_time - start_time) * 1000, 2)))
np_array = np.arange(1e6)
start_time = time.time()
np_array = np_array * 5
end_time = time.time()
print('Numpy array time: {}ms'.format(round((end_time - start_time) * 1000, 2)))
print('What sup!')
'''
'''
三个关键知识点,即:
安装 Numpy
Windows 系统: pip install numpy
Mac 系统: pip3 install numpy
视图与副本
创建视图,我们可以通过两种方法:Numpy 的切片操作以及调用view() 函数。
浅拷贝在 Python 原生列表中,需要区分是否是嵌套列表。在 Numpy 中则简单一些,无论数组的维数是多少:在数组是1维的时候,规律和列表有些不一样,这里要特别注意
对视图或切片结果进行元素层面的修改时,操作的效果会反映到原始数组里。
视图的纬度更改并不会传递到原始数组 :改变视图的形状
import numpy as np
arr_0 = np.arange(12).reshape(3,4)
view_0 = arr_0.view()
view_0
Out: array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
# 从id看,二者并不具备同一性。
id(arr_0) is view_0
Out: False
# 更改视图的元素,则原始数据会产生联动效果
view_0[1,1] = 100
arr_0
Out: array([[ 0, 1, 2, 3],
[ 4, 100, 6, 7],
[ 8, 9, 10, 11]])
# 更改视图的维度:
# 视图的纬度更改并不会传递到原始数组
view_0.shape = (4,3)
print("arr_0 shape:", arr_0.shape, "view_0 shape:", view_0)
Out: arr_0 shape: (3, 4) view_0 shape: (4, 3)
# 利用切片创建视图朋友们都很熟悉了,我们来看一下在一维数组上测试的效果:
# 对一维数组切片,并对切片后的结果进行更改,查看是否对原始数组产生影响
arr_1 = np.arange(12)
slice_1 = arr_1[:6]
slice_1[3] = 99
slice_1
Out: array([ 0, 1, 2, 99, 4, 5])
# arr_1的第四个元素发生变成了99。在数组是1维的时候,规律和列表有些不一样,这里要特别注意。
arr_1
Out: array([ 0, 1, 2, 99, 4, 5, 6, 7, 8, 9, 10, 11])
副本
副本也就是深拷贝,相对而言对内存的处理比较粗暴,也比较好理解。建立副本前后,两个变量是完全独立的。 Numpy建立副本的方法稍有不同。方法一,是利用Numy自带的copy函数;方法二,是利用deepcopy()函数
介绍
Numpy 最重要的一个特点就是它可以快速地创建一个 N 维数组对象(即 ndarray ,本文在 ndarray 对象和 数组 并不做概念上的区分),然后你可以利用 ndarray 这种数据结构非常高效地执行一些数学运算,并且语法风格和 Python 基本一致
ndarray 是一个通用的同构数据多维容器,其中的所有的元素必须是相同的类型, Numpy 会根据输入的实际情况进行转换。「也就是如果创建的时候,没有指定数据类型,那 Numpy 就会以数组中最小的数据类型为数据。
N 维数组对象
其他数据类型
matrix 矩阵
创建
np.array:接受一个序列型对象(比如列表),并转化为 ndarray 对象。
一维数组 | data = np.array([2, 4, 6.5, 8]) |
---|---|
二维数组 | data = np.array([[1, 2, 3], [4, 5, 6]]) |
data = np.array( [ [[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]] ] ) | |
四维数组 | data = np.array( [ [[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]], [[[13, 14, 15], [16, 17, 18]], [[19, 20, 21], [22, 23, 24]]] ] |
数组属性
数据类型 dtype
维度的数量 ndim
对象的尺度 shape
对于矩阵,即 n 行 m 列,shape 是一个元组(tuple)
元素的数量 size
相当于 shape 中 nXm 的值
各个元素内存 itemsize
性返回数组中各个元素所占用的字节数大小
数组字节数 nbytes
整个数组所需的字节数量,其值等于数组的 size 属性值乘以 itemsize 属性值
数组转置 T
复数实部 real
数组虚部 imag
即可迭代的对象 flat
返回一个 numpy.flatiter 对象
import numpy
np.array([1.22,3.45,6.779], dtype='int8')
# array([1, 3, 6], dtype=int8)
np.arange(4, dtype=float)
# array([0., 1., 2., 3.])
np.arange(4, dtype='D')
# array([0.+0.j, 1.+0.j, 2.+0.j, 3.+0.j])
a = np.array([[1,2,3], [7,8,9]])
a.ndim
# 2
a.shape
# (2, 3)
a.size
# 6
a.itemsize
# 8
a.nbytes
# 48
a.T
'''
array([[1, 7],
[2, 8],
[3, 9]])
'''
d = np.array([1.2+2j, 2+3j])
d.real
# array([1.2, 2. ])
d.imag
# array([2., 3.])
e = np.arange(6).reshape(2,3)
e
f = e.flat
for item in f:
print(item)
array
基于:list、tuple、Dataframe
一维数组用 print 输出的时候为 [1 2 3 4],跟 python 的列表是有些差异的,没有“,”
在创建二维数组时,在每个子 list 外面还有一个“[]”,形式为“[[list1], [list2]]”
import numpy as np
import pandas as pd
arr2 = np.array([[1,2,4], [3,4,5]])
arr_tuple = np.array((1,2,3,4))
df = pd.DataFrame({
'A':[1,2,3],'B':[4,5,6],'C':[7,8,9]})
s=np.array(df.values)
arange
基于 固定步长
自动判断数据类型,
np.arange(3)
# array([0, 1, 2])
np.arange(3.0)
# array([0., 1., 2.])
np.arange(3,7)
# array([3, 4, 5, 6])
np.arange(3,7,2)
# array([3, 5])
# 二维数组
arr2 = np.array([np.arange(3), np.arange(3)])
arr2
'''
array([[0, 1, 2],
[0, 1, 2]])
'''
## 创 建 三 维 数 组
arr = np.arange(24).reshape(2,3,4)
linspace
np.linspace(start, stop[, num=50[, endpoint=True[, retstep=False[, dtype=None]]]]])
start、stop 参数,和 arange() 中一致;
num 为待创建的数组中的元素的个数,默认为50
endpoint=True,则为左闭右闭区间,默认为 True;endpoint=False,则为左闭右开区间
retstep 用来控制返回值的形式。默认为 False,返回数组;若为 True,则返回由数组和步长组成的元祖
linspace(a, b , c, d) :在[a, b]中均匀的取c个数,d为False 不包含b, 默认为True
代码
# 不设置 endpoint,默认为 Ture,结果为左闭右闭区间
In [43]: arr_uniform3 = np.linspace(1,99, 11)
In [44]: arr_uniform3
Out[44]: array([ 1. , 10.8, 20.6, 30.4, 40.2, 50. , 59.8, 69.6, 79.4, 89.2, 99. ])
# 设置 endpoint 为 False,结果为左闭右开区间
In [41]: arr_uniform4 = np.linspace(1,99, 11, endpoint=False)
In [42]: arr_uniform4
Out[42]:
array([ 1. , 9.90909091, 18.81818182, 27.72727273, 36.63636364,
45.54545455, 54.45454545, 63.36363636, 72.27272727, 81.18181818,
90.09090909])
# retstep 设置为 True,分别返回数组和步长
In [45]: arr_uniform5 = np.linspace(1,99, 11, retstep=True)
In [46]: arr_uniform5
Out[46]:
(array([ 1. , 10.8, 20.6, 30.4, 40.2, 50. , 59.8, 69.6, 79.4, 89.2, 99. ]),
9.8)
normal
指定分布(如标准正态分布)
20个指定分布(如标准正态分布)的数
代码
tem = np.random.normal(0, 1, 20)
np.nan 空值
np.frompyfunc 创建函数
将计算单元素的函数转换成,能对数组的每个元素进行操作的函数即可。
三个输入参数,分别是待转化的函数、函数的输入参数的个数、函数的返回值的个数
代码
# 定义函数,购买x件订单,返回订单金额
def order(x):
if x>=100:
return 20*0.6*x
if x>=50:
return 20*0.8*x
if x>=10:
return 20*0.9*x
return 20*x
# frompyfunc函数
income = np.frompyfunc(order, 1, 1)
np.zeros 全为0的数组
np.zeros([4,5])
np.ones([2,3])
eye = np.eye(7)
np.diag([5,5,5,5,5])
np.ones 生成元素全为1的数组:
np.eye 单位矩阵形式的数组(n*n ,对角为1):
np.diag 矩阵对角元素提取
geomspace() 指数等比数列
geomspace(start, stop, num=50, endpoint=True, dtype=None)
# start 和 stop,分别为区间的起始和终止值,为强制参数;
# num 为待生成等比数列的长度,指定后,程序会自动计算取等比数列的公比;
# endpoint默认为 True,结果为左闭右必区间。否则为 False,左闭右开区间;
# 起始项为2,结束项为16,数列的长度为4。这里要注意,默认是左闭右闭的数组
In [51]: arr_geo0 = np.geomspace(2,16,4)
In [52]: arr_geo0
Out[52]: array([ 2., 4., 8., 16.]
logspace 对数等比数列
logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None)
# start:区间起始值为 base 的 start 次方
# stop:区间终止值为 base 的 stop 次方(是否取得到,需要设定参数 endpoint)
# num:为待生成等比数列的长度。按照对数,即 start 和 stop 值进行等分。默认值为 50
# endpoint:若为 True(默认),则可以取到区间终止值,即左闭右闭区间,规则同上
# 起始项为2^1,结束项为2^4,数列的长度为4。这里要注意,起始项是以base为底,start值为指数的幂。
# 另外,因为logspace的参数比较多,建议除了start和stop,其他的参数都以键值对的形式进行传参,避免发生错误
In [53]: arr_geo1 = np.logspace(1, 4, num=4, base=2)
In [54]: arr_geo1
Out[54]: array([ 2., 4., 8., 16.])
random.rand ----[0, 1)之间的均匀分布的随机数组
生成 [0,1) 之间的数据,包含 0,不包含 1
函数的输入为若干个整数,表示输出随机数的大小为 d0×d1× …×dn
如果没有参数输入,则返回一个 float 型的随机数
# 产生一个大小为3×2,符合0-1之间的均匀分布的数组
In [57]: arr_rand0 = np.random.rand(3, 2) # 3 行 2 列
In [58]: arr_rand0
Out[58]:
array([[0.59348424, 0.30368829],
[0.73058467, 0.66220976],
[0.6186512 , 0.32079605]])
生成 [0,1) 之间的浮点数
numpy.random.random_sample(size=None)
numpy.random.random(size=None)
numpy.random.ranf(size=None)
numpy.random.sample(size=None)
random.uniform— [low, high) 之间的均匀分布
# uniform 方法可以指定产生随机数的范围 [low, high),size 为数组的形状,输入格式为整形(一维)或者整形元祖
# 如果不指定size的话,则返回一个服从该分布的随机数
numpy.random.uniform(low=0.0, high=1.0, size=None)
# 产生一个大小为3×2,符合0-10之间的均匀分布的数组
arr_rand1 = np.random.uniform(1, 10, (3, 2))
arr_rand1
Out:
array([[6.72617294, 5.32504844],
[7.6895909 , 6.97631457],
[1.3057397 , 3.51288886]])
random.randn 服从标准正态分布的数组
# 该方法和rand类似,函数的输入为若干个整数,表示输出随机数的大小为d0×d1× …×dn
# 如果没有参数输入,则返回一个服从标准正态分布的float型随机数
numpy.random.randn(d0, d1, …, dn)
numpy.random.normal 服从 μ=loc,σ=scale 的正态分布的数组
random.randint 指定区间 [low, high) 中离散均匀抽样的数组
random.choice 从给定的一维数组中生成随机数
概率抽样:
对具体样本进行有放回或者无放回的抽样
numpy.random.seed() 使得随机数据可预测
设置相同的 seed,每次生成的随机数相同
如果不设置 seed,则每次会生成不同的随机数
当数组跟一个标量进行数学运算时,标量需要根据数组的形状进行扩展,然后执行运算。这个扩展的过程称为“广 播(broadcasting)”
直接加减乘除
b —array([[ 0, 1, 20, 3, 4, 5], [ 6, 7, 8, 9, 10, 11]])
d = b + 2 —array([[ 2, 3, 22, 5, 6, 7], [ 8, 9, 10, 11, 12, 13]])
描述性统计
np.mean() 均值
np.median() 中位数
percentile 分位数
np.var() 返回方差(variance)
np.std() 回标准偏差(standard deviation)
np.cov(arr1,arr2) 相关性矩阵
np.corrcoef(arr1,arr2) 协方差矩阵
convolve 移动值移动平均值
np.convolve(df[‘col2’], np.ones(3)/3, mode=‘valid’)
np.sqrt 开方
df[[‘salary’]].apply(np.sqrt)
np.sum() 求和
new.sum(axis=1)
np.mud 余数
np.multiply(a,b) 乘
np.max() 最大值
np.min() 最小值
np.ptp() 数组沿指定轴返回最大值减去最小值
np.cumsum() 累加值
逐层累加,返回相同形状的数组
b.resize(4,3)
array([[ 0, 1, 20],
[ 3, 4, 5],
[ 6, 7, 8],
[ 9, 10, 11]])
np.cumsum(b, axis=1)
array([[ 0, 1, 21],
[ 3, 7, 12],
[ 6, 13, 21],
[ 9, 19, 30]], dtype=int32)
np.cumprod() 累乘积值
沿指定轴方向进行累乘积
np.cumprod(b,axis=1)
array([[ 0, 0, 0],
[ 3, 12, 60],
[ 6, 42, 336],
[ 9, 90, 990]], dtype=int32)
np.dot 矩阵乘法
np.linalg.det 行列式
np.linalg.inv 矩阵求逆
np.linalg.svd() 矩阵SVD分解
np.squeeze(arr) 压缩矩阵
从数组的形状中删除单维度条目,即把shape中为1的维度去掉
arr = np.random.randint(1,10,[3,1])
arr
[[3]
[8]
[5]]
np.squeeze(arr)
[3 8 5]
np.linalg.solve() 求解线性方程组
输入:
A = np.array([[1, 2, 3], [2, -1, 1], [3, 0, -1]])
b = np.array([9, 8, 3])
求解Ax = b
x = np.linalg.solve(A, b)
np.repeat 重复
参数:数据、次数、轴向
数据d的每一行复制3次
np.repeat(d,3,axis=0)
copy 副本
索引:值
arr2[2] #第三行,可以理解为行索
arr2[2,1]/arr2[2][1] #第三行第二列
arr2[:,2:4] #访问第三列
arr2[1:3] #2行和3行
arr2[1:,2:] #第2行到最后一行,第3列到最后一列
arr[2:8:2]#索引2开始到索引8停止,间隔为2
直接查
np.take根据位置列表查找
unique 不同元素(计数)
isin 包含
注意包含和等于的区别:
包含是有值存在,等于是位置和值都对应
intersect1d 获得相同元素
setdiff1d 获得不同元素
类似:
arr3 = arr1[~(np.isin(arr1,arr2))]
extract 输出满足条件的数据
np.where 条件判断
3个参数,分别是判断条件、为真时的值,为假时的值
返回:tuple, 包含各维度数组猜想:按照各个维度分别进行判断,返回符合条件的索引
np.where(c!=b)
(array([2, 2]), array([2, 3]))
np.argwhere 位置
argmax 位置
argmin位置
argsort 位置
np.nan 空值
n’p.sort() 排序
参数 | 含义 |
---|---|
a | 排序的数组 |
axis | 排序的方向,None表示展开来排序,默认值为-1,表示沿最后的轴排序,可选有0、1 |
kind | 排序的算法,包含快排’quicksort’、混排’mergesort’、堆排’heapsort’, 默认为‘quicksort’ |
order | 一个字符串或列表,可以设置按照某个属性进行排序 |
s = np.array([1,2,3,4,3,1,2,2,4,6,7,2,4,8,4,5])
np.sort(s)
astype 数组 成指定类型
b.astype(float)
array([[ 0., 1., 20., 3., 4., 5.], [ 6., 7., 8., 9., 10., 11.]])
arr1.flags.writeable 权限 只读模式
tolist() 数组转换成 list
b.tolist()
[[0, 1, 20, 3, 4, 5], [6, 7, 8, 9, 10, 11]]
pad 数据环绕
array([[ 0, 666, 666],
[666, 666, 666],
[666, 666, 666]])
new = np.pad(result,pad_width = 2,constant_values=4)
array([[ 4, 4, 4, 4, 4, 4, 4],
[ 4, 4, 4, 4, 4, 4, 4],
[ 4, 4, 0, 666, 666, 4, 4],
[ 4, 4, 666, 666, 666, 4, 4],
[ 4, 4, 666, 666, 666, 4, 4],
[ 4, 4, 4, 4, 4, 4, 4],
[ 4, 4, 4, 4, 4, 4, 4]])
reshape 形状转换
方法非常灵活地应用于调整数组的大小,但是不改变数组的长度。即长度 100 的数组,你可以非常方便地调整为 1×100 或者是 4×25 或者是 5×20。这点在将横向量调整为列向量的时候非常有用。
b =ndarray([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]])
b.reshape(4,3)
array([[ 0, 1, 2], [ 3, 4, 5], [ 6, 7, 8], [ 9, 10, 11]])
b :array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]])
resize() 维度变化
函数 resize()的作用跟 reshape()类似,但是会改变所作用的数组,相当于有 inplace=True 的效果
b.resize(4,3)
b
array([[ 0, 1, 2], 6[ 3, 4, 5], 7 [ 6, 7, 8], 8 [ 9, 10, 11]])
reshape/resize() 两者的区别在于返回拷贝(copy)还是返回视图(view)
b.shape 用 tuple 指定数组的形状
b.shape=(2,6)
array([[ 0, 1, 20, 3, 4, 5], [ 6, 7, 8, 9, 10, 11]])
ravel 多维数组转换成一维数组
而 ravel() 返回的是视图(view),会影响原始矩阵
b.ravel()
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
flatten 返回一份拷贝
需要分配新的内存空间,对 拷贝所做的修改不会影响原始矩阵
b.flatten()
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
transpose 转置
数组转置的属性(T),也可以通过 transpose() 函数来实现
b.transpose()
array([[ 0, 6], [ 1, 7], [20, 8], [ 3, 9], [ 4, 10], [ 5, 11]])
hstack() 水平叠加
b
array([[ 0, 1, 20, 3, 4, 5], [ 6, 7, 8, 9, 10, 11]])
c
array([[ 0, 2, 40, 6, 8, 10], 6 [12, 14, 16, 18, 20, 22]])
np.hstack((b,c))
np.column_stack((b,c))
array([[ 0, 1, 20, 3, 4, 5, 0, 2, 40, 6, 8, 10],
[ 6, 7, 8, 9, 10, 11, 12, 14, 16, 18, 20, 22]])
np.vstack((b,c))
array([[ 0, 1, 20, 3, 4, 5],
[ 6, 7, 8, 9, 10, 11],
[ 0, 2, 40, 6, 8, 10],
[12, 14, 16, 18, 20, 22]])
column_stack()水平叠加
通过设置 axis 的值来设置叠加方向:
axis=1 时,沿水平方向叠加
axis=0 时,沿垂直方向叠加
concatenate()效率更高
np.concatenate((c,b),axis =0)
vstack()
row_stack() 垂直叠加
concatenate() z综合
append
np.append(a,10)
array([ 0, 1, 2, 3, 4, 10])
b
array([[ 0, 1, 20, 3, 4, 5],
[ 6, 7, 8, 9, 10, 11]])
np.hsplit(b, 2)
[array([[ 0, 1, 20], [ 6, 7, 8]]), array([[ 3, 4, 5], [ 9, 10, 11]])]
np.vsplit(b, 2)
[array([[ 0, 1, 20, 3, 4, 5]]), array([[ 6, 7, 8, 9, 10, 11]])]
np.split(b,2,axis=0)
[array([[ 0, 1, 20, 3, 4, 5]]), array([[ 6, 7, 8, 9, 10, 11]])]
np.piecewise 数组分类
参数一 x:表示要进行操作的对象
参数二:condlist,表示要满足的条件列表,可以是多个条件构成的列表
参数三:funclist,执行的操作列表,参数二与参数三是对应的,当参数二为true的时候,则执行相对应的操作函数,其余的默认以0填充,可以多设置一个参数为默认
np.piecewise(arr,[arr>=7,arr<3],[1,0,4]),其余默认4
返回值:返回一个array对象,和原始操作对象x具有完全相同的维度和形状
(1)案例一
x = np.arange(0,10)
print(x)
xx=np.piecewise(x, [x < 4, x >= 6], [-1, 1])
print(xx)
运行结果为:
[0 1 2 3 4 5 6 7 8 9]
[-1 -1 -1 -1 0 0 1 1 1 1]
即将元素中小于4的用-1替换掉,大于等于6的用1替换掉,其余的默认以0填充。其实这里的替换和填充就是function,这不过这里的function跟简单粗暴,都用同一个数替换了。实际上,上面的代码完全等价于下面的代码:
x = np.arange(0,10)
def func1(y):
return -1
def func2(y):
return 1
xxx=np.piecewise(x, [x < 4, x >= 6], [func1, func2])
print(xxx)
运行结果为:
[-1 -1 -1 -1 0 0 1 1 1 1] #同上面一样
(2)案例二——定义相关的操作函数
x = np.arange(0,10)
#元素进行平方
def func2(y):
return 1ef func1(y):
return y**2
#元素乘以100
def func2(y):
return y*100
xxx=np.piecewise(x, [x < 4, x >= 6], [func1, func2])
print(xxx)
运行结果为:
[ 0 1 4 9 0 0 600 700 800 900]
(3)案例三——使用lambda表达式
x = np.arange(0,10)
xxxx=np.piecewise(x, [x < 4, x >= 6], [lambda x:x**2, lambda x:x*100])
print(xxxx)
运行结果为:
[ 0 1 4 9 0 0 600 700 800 900]
Pandas简介:
Python Data Analysis Library(数据分析处理库) 或 pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。
基于两种数据结构,Pandas可以对数据进行导入、清洗、处理、统计和输出。
官方 | https://pandas.pydata.org/pandas-docs |
---|---|
笔记 | [https://github.com/datawhalechina/joyful-pandas/blob/master/%E7%AC%AC1%E7%AB%A0%20Pandas%E5%9F%BA%E7%A1%80.ipynb](https://github.com/datawhalechina/joyful-pandas/blob/master/第1章 Pandas基础.ipynb) |
支持的数据类型:
默认的数据类型是int64,float64.
数据格式
一维数组 -Series
定长的字典序列
只允许存储相同的数据类型,这样可以更有效的使用内存,提高运算效率
pandas.Series(data,index,dtype,name)。
data可以为列表,array或者dict。
index表示索引,必须与数据同长度,name代表对象的名称
index 和 values。在 Series 结构中,index 默认是 0,1,2,……递增的整数序列,也可以自己指定比如 index=[‘a’, ‘b’, ‘c’, ‘d’]。
series有相当多的方法可以调用
print([attr for attr in dir(s) if not attr.startswith('_')])
['T', 'a', 'abs', 'add', 'add_prefix', 'add_suffix', 'agg', 'aggregate', 'align', 'all', 'any', 'append', 'apply', 'argmax', 'argmin', 'argsort', 'array', 'asfreq', 'asof', 'astype', 'at', 'at_time', 'attrs', 'autocorr', 'axes', 'b', 'backfill', 'between', 'between_time', 'bfill', 'bool', 'c', 'clip', 'combine', 'combine_first', 'compare', 'convert_dtypes', 'copy', 'corr', 'count', 'cov', 'cummax', 'cummin', 'cumprod', 'cumsum', 'd', 'describe', 'diff', 'div', 'divide', 'divmod', 'dot', 'drop', 'drop_duplicates', 'droplevel', 'dropna', 'dtype', 'dtypes', 'duplicated', 'e', 'empty', 'eq', 'equals', 'ewm', 'expanding', 'explode', 'factorize', 'ffill', 'fillna', 'filter', 'first', 'first_valid_index', 'floordiv', 'ge', 'get', 'groupby', 'gt', 'hasnans', 'head', 'hist', 'iat', 'idxmax', 'idxmin', 'iloc', 'index', 'infer_objects', 'interpolate', 'is_monotonic', 'is_monotonic_decreasing', 'is_monotonic_increasing', 'is_unique', 'isin', 'isna', 'isnull', 'item', 'items', 'iteritems', 'keys', 'kurt', 'kurtosis', 'last', 'last_valid_index', 'le', 'loc', 'lt', 'mad', 'map', 'mask', 'max', 'mean', 'median', 'memory_usage', 'min', 'mod', 'mode', 'mul', 'multiply', 'name', 'nbytes', 'ndim', 'ne', 'nlargest', 'notna', 'notnull', 'nsmallest', 'nunique', 'pad', 'pct_change', 'pipe', 'plot', 'pop', 'pow', 'prod', 'product', 'quantile', 'radd', 'rank', 'ravel', 'rdiv', 'rdivmod', 'reindex', 'reindex_like', 'rename', 'rename_axis', 'reorder_levels', 'repeat', 'replace', 'resample', 'reset_index', 'rfloordiv', 'rmod', 'rmul', 'rolling', 'round', 'rpow', 'rsub', 'rtruediv', 'sample', 'searchsorted', 'sem', 'set_axis', 'shape', 'shift', 'size', 'skew', 'slice_shift', 'sort_index', 'sort_values', 'squeeze', 'std', 'sub', 'subtract', 'sum', 'swapaxes', 'swaplevel', 'tail', 'take', 'to_clipboard', 'to_csv', 'to_dict', 'to_excel', 'to_frame', 'to_hdf', 'to_json', 'to_latex', 'to_list', 'to_markdown', 'to_numpy', 'to_period', 'to_pickle', 'to_sql', 'to_string', 'to_timestamp', 'to_xarray', 'transform', 'transpose', 'truediv', 'truncate', 'tz_convert', 'tz_localize', 'unique', 'unstack', 'update', 'value_counts', 'values', 'var', 'view', 'where', 'xs']
二维的表格型数据结构–DataFrame
数据框其实就是二维的数据结构,数据分析中最常用
pandas.DataFrame(data,index,dtype,columns)。
data | 列表 Array dict | |
---|---|---|
Index | 行索引 | 列表 |
columns | 列名 | 列表 |
三维的数组-Panel
可以理解为DataFrame的容器
以时间为索引的Series–Time- Series
方法名称 | 说明 | |
---|---|---|
values | 返回对象所有元素的值 | |
index | 返回行索引 | |
dtypes | 每列的数据类型 | |
ndim | 对象的维度 | |
size | 对象的个数 | |
info() | 概览,列:索引,列数,列名,空值,数据类型,数据类型汇总,内存大小 | |
describe() | 数值型列的汇总统计 包括: count, mean, std, min, max 25% 50% 75% | |
describe(include=[‘O’]) 查看字符串类型(非数字)的整体情况; | ||
head() | 前几行 | |
tail() | 后几行 | |
shape() | 数据形状:行列数 | 列数 df.shape[1] |
columns | 列标签(只针对dataframe数据结构) | |
any | ||
value_caunt | 字段的不同值,只能逐个字段传入,无法用数组传入 | train_data[‘Sex’].value_counts() |
基本运算
常用的统计函数,如果遇到空值 NaN,会自动排除
统计个数 | count() | 空值NaN不计算 |
---|---|---|
值的次数 | value_counts() | |
平均值 | mean() | |
上下值的平均值 | interpolate() | 用途**:**将空值用上下值的平均值填充 |
最值 | ||
最小值 | min() | |
局部最大值 它前一个与后一个数字的都大的数字 | ||
最小值的索引位置 | argmin() | |
最大值的索引位置 | argmax() | |
最小值的索引值 | idxmin() | |
最大值的索引值 | dxmax() | |
最大值 | max() | |
中位数 | median() | |
总和 | sum() | |
方差 | var() | |
标准差 | std() | |
分位数 | quantile() | |
统计大礼包 | Describe() |
计算
减 | - | df[“salary”] - df[0] | |
---|---|---|---|
diff | 上下行之间****差值 | 前一天与后一天收盘价的差值 data[‘收盘价(元)’].diff() | |
变化率 | pct_change | 上下行之间 | data[‘收盘价(元)’].pct_change() |
数据分组运算
groupby 创建分组对象
计算项
单维度分组默认计为分组维度
多维度分组可以在调用方法时指定对应的组:
如count、mean 、 median 、 max和min等
默认计算列
df[['district','salary']].groupby(by='district').mean()
指定计算列
group_2=titanic_pd.groupby(['Sex','Age_Type'])['Fare'].mean()
结合agg函数
聚合函数使用 agg
针对分组后的对象, 对各列分别进行计算
df[["salary","score"]].agg([np.sum,np.mean,np.min])
df.agg({"salary":np.sum,"score":np.mean})
独立写法
a1=grouped.agg({'total_items':'sum','Food%':['mean','median']})
结合numpy
import numpy as np
a1=grouped.agg({'total_items':np.sum,'Food%':np.mean})
分组对象和apply函数
透视图与
pivot_table 根据行或列对数据绘制
pivot_table( data, index, columns,values, aggfunc, fill_value, margins, margins_name=)
参数:
Index : 行分组键
columns: 列分组键
values: 分组的字段,只能为数值型变量
aggfunc: 聚合函数
margins: 是否需要总计
values_1=['Food%','Fresh%']
a=pd.pivot_table(data=df,index='weekday',columns='customer',values=values_1,aggfunc=[np.sum,np.mean],margins=True,margins_name='sum')
交叉表 pd.crosstab
交叉表用于计算分组频率,计数/百分比分布
pd.crosstab(index,columns,normalize)
参数:
Index: 行索引
Columns: 列索引
Normalize: 数据对数据进行标准化
index表示行
column表示列
b=pd.crosstab(index=df['weekday'],columns=df['discount%'],margins=True,normalize='index')
离散化
等宽分箱 pd.cut
pandas.cut(x, bins, right=True, labels=None, retbins=False, precision=3, include_lowest=False)
参数:
x, | 类array对象,且必须为一维,待切割的原形式 |
---|---|
bins, | 整数、序列尺度、或间隔索引。如果bins是一个整数,它定义了x宽度范围内的等宽面元数量,但是在这种情况下,x的范围在每个边上被延长1%,以保证包括x的最小值或最大值。如果bin是序列,它定义了允许非均匀bin宽度的bin边缘。在这种情况下没有x的范围的扩展。 |
right, | 布尔值。是否是左开右闭区间,right=True,左开右闭,right=False,左闭右开 |
labels, | 用作结果箱的标签。必须与结果箱相同长度。如果FALSE,只返回整数指标面元(划分的区间/切割标准)。 |
retbins, | 布尔值。是否返回面元 |
precision, | 整数。返回面元的小数点几位 |
include_lowest | 布尔值。第一个区间的左端点是否包含 |
bins = [0,5000, 20000, 50000]
group_names = ['低', '中', '高']
df['categories'] = pd.cut(df['salary'], bins, labels=group_names)
等频分割 pd.qcut
(x, q, labels=None, retbins=False, precision=3, duplicates=’raise’)
参数:
q | 整数或分位数组成的数组。 |
---|---|
q, | 整数 或分位数数组 整数比如 4 代表 按照4分位数 进行切割 |
labels, | 用作结果箱的标签。必须与结果箱相同长度。如果FALSE,只返回整数指标面元。 |
pandas内置了10多种数据源读取函数,常见的就是CSV和EXCEL,在运行的过程可能会存在缺少 xlrd 和 openpyxl 包的情况
读取 read_csv()
filepath_or_buffer 文件路径 | Union[str, Path, IO[AnyStr]] str 最好 |
---|---|
encoding | 常用编码为utf-8、gbk 、gbk2312和gb18030等 |
usecols | 读取指定列 |
nrows 读取的行数 | nrows=10 |
dype 读取的类型 | dtype={ ‘customer’:str,‘order’:str} dtype =str 全部数据为str |
ndex_col 索引列 | ndex_col=[3,0] |
converters | 读取数据并在读取数据时修改: 将薪资大于10000的为改为高 converters={‘薪资水平’: lambda x: ‘高’ if float(x) > 10000 else ‘低’} |
na_values 空值 | na_values='Na |
写文件 to_csv
Excel
层次化索引
基础索引方式,就是直接引用列表
列表由被引用的列名组成
loc
通过行索引 “Index” 中的具体值来取行数据,第1个参数都是对行操作。第2个参数是对列。
条件搜索
行 | df.loc[3:6] |
---|---|
行,列 | df.loc[3:6,[‘user_id’,‘auction_id’]] |
条件搜索 | a=df.user_id==‘917056007’ b=[‘user_id’,‘auction_id’] print(df.loc[a,b]) |
多层索引 | |
行多层索引 | df3.loc[(a,b),:] a和b分别代表第一层和第二层的索引 df.loc[(50008168,444069173),1] |
第一层索引多选 | df.loc[([28,50014815])] |
第二层索引多个选择 | df.loc[28].loc[[82830661,532110457]] |
iloc
筛选位置,通过行号来取行数据
df.iloc[0:5,1:4]
df.iloc[::20, :][[‘薪资水平’]]
隔*行进行一次抽样
take
f['col1'].take([1,10,15])
\# 等价于
df.iloc[[1,10,15],0]
条件查询
范围 :between
参数:
left – Left boundary.
right – Right boundary.
inclusive – Include boundaries True/Flase
> & | ~
包含:isin
遍历 df.iterrows()
for index,row in df.iterrows():
nums = re.findall('\d+',row[2])
df.iloc[index,2] = int(eval(f'({nums[0]} + {nums[1]}) / 2 * 1000'))
采样 resample
按周为采样规则,取一周收盘价最大值
data[‘收盘价(元)’].resample(‘W’).max()
data[‘收盘价(元)’].resample(‘7D’).max()
排序 argsort
判断类型 type
重复值 duplicated
逐行判断 默认判断:行之间是否有重复值,返回布尔值 | df.duplicated() |
---|---|
展示重复行 | df[df.duplicated()] |
计数重复行 | np.sum(df.duplicated()) |
删除重复行 | df.drop_duplicates(subset=[‘Condition’,‘Condition_Desc’,‘Price’,‘Location’],inplace=True) |
日期
dataframe时间戳数据一般为
查找空值 df.isnull()
统计缺失比例
print(**'每行缺失值的统计:'**,df.apply(lambdax:sum(x.isnull())/len(x),axis=0))
**每列数据缺失值**
ata.isnull().sum()
任何值 any
reset_index
df.index =[],
df.set_index
swaplevel()
改列名rename
直接修改列名
修改列名为****col1,col2,col3
df.columns = [‘col1’,‘col2’,‘col3’]
列顺序
顺序颠倒
数据滑动窗口
rolling
5日均线:5个数据取均值作为一个数据滑动窗口
data[‘收盘价(元)’].rolling(5).mean()
计算移动窗口
expending
计算开盘价的移动窗口均值
data[‘开盘价(元)’].expanding(min_periods=1).mean()
顺序
sort_values ascending:False 降序
df.sort_values(‘salary’, ascending=False)
后移 shift
向后/前移动5行
data.shift(5)
data.shift(-5)
反转df的行
df.iloc[::-1, :]
空值填充 df.fillna()
单列填充
多列填充
直接修改
df.col1
将第一列大于50的数字修改为’高’
df.col1[df[‘col1’] > 50]= ‘高’
df.map
直接传入 df[‘New’]
titanic_pd[‘Family_Size’]=titanic_pd[‘SibSp’]+titanic_pd[‘Parch’]
插入 df.insert
insert(loc: int, column: Any, value: Any,allow_duplicates: Any = False)
loc: | int,插入的位置。 |
---|---|
column: | Any列名 |
value: | Any插入的数据。 |
allow_duplicates: | Any = False |
df.insert(0,‘auction_id’,auction_id)
drop
labels | Index labels to drop. |
---|---|
axis | Redundant for application on Series. axis表示作用轴:axis =1 按列删除 axis = 0 按照行 |
index | Redundant for application on Series, but ‘index’ can be used instead of ‘labels’. |
columns | No change is made to the Series; use ‘index’ or ‘labels’ instead. |
level | For MultiIndex, level for which the labels will be removed. |
inplace | If True, do operation inplace and return None. inplace=True表示是否对原数据生效 , |
errors | If ‘ignore’, suppress error and only existing labels are dropped. |
del
drop_duplicates()函数
参数 | 说明 |
---|---|
subset | 根据指定的列名进行去重,默认整个数据集 |
keep | 可选{‘first’, ‘last’, False},默认first,即默认保留第一次出现的重复值,并删去其他重复的数据,False是指删去所有重复数据。 |
inplace | 是否对数据集本身进行修改,默认False |
空值 df.dropna()
parameters | 详解 |
---|---|
axis | default 0指行,1为列 |
how | {‘any’, ‘all’}, default ‘any’指带缺失值的所有行;'all’指清除全是缺失值的行 |
thresh | int,保留含有int个非空值的行 |
subset | 对特定的列进行缺失值删除处理 |
inplace | 这个很常见,True表示就地更改 |
字符串
去空格
去空格 | |
---|---|
删除两边空格 特定字符 | strip |
#删除左边空格 | lstrip |
#删除右边空格 | rstrip |
列转换为list to_list() df[‘grammer’].to_list()
合并为一列 + 数据类型需要相同 df[“test1”] = df[“salary”].map(str) + df[‘education’]
文本格式转换为日期格式
to_datetime()
df[‘New_day’]=pd.to_datetime(df[‘day’],format=’%Y%m%d’)
to_pydatetime()
timedelta
时间差数据:转换为指定时间单位的数值。
df[‘时间差’]=df[‘time_diff’]/pd.Timedelta(‘1 D’)
利用除法
类似的 Y M D H m
数据格式 astype
df[‘time_diff’].astype(‘timedelta64[Y]’)
‘timedelta64[Y]’ df2[‘Chinese’].astype(‘str’)
df2[‘Chinese’].astype(np.int64) ‘str’
取消使用科学计数法 df.round(3)
转换为百分数 format df.style.format({‘data’: ‘{0:.2%}’.format})
大小写转换 提取
str Pandas中提供了字符串的函数,但只能对字符型变量进行使用 ,
通过str方法访问相关属性 ,可以使用字符串的相关方法进行数据处理
全部大写 str.upper() df2.columns.str.upper()
全部小写 str.lower() df2.columns = df2.columns.str.lower()
首字母大写 str.title() df2.columns = df2.columns.str.title()
按字符位置提取 str[1:] f1[‘Price_1’]=df1[‘Price’].str[1:]
替换字符 str.replace df1[‘Price_1’]=df1[‘Price_1’].str.replace(r’,’,’’)
时间转换为月-日 strftime df.ix[i,0].to_pydatetime().strftime("%m-%d")
拆分 str.split
数据表合并 连接前确保对应字段的数据类型的一致性
merge
参数
left: 数据1 | Any, |
---|---|
right: 数据2 | Any, |
how:连接方式 | =“inner”,“left”,“right” |
on: | Any = None, |
left_on:被连接的字段 | Any = None, |
right_on:被连接的字段 | Any = None, |
left_index: | bool = False, |
right_index: | bool = False, |
sort: | bool = False, |
suffixes: | Tuple[str, str] = ("_x", “_y”), |
copy: | bool = True, |
indicator: | bool = False, |
validate: | Any = None) |
案例
内联接
df_2=pd.merge(left=df,right=df1,how=‘inner’,left_on=‘user_id’,right_on=‘user_id’)
使用merge通过索引合并两个Dataframe
df2 = df.merge(df2, left_index=True, right_index=True, how=‘left’)
concat
一般用作相同结构的表行合并,多张表合并可以建立循环
参数
axis: | Any = 0 axis =1用于横向,0代表纵向 |
---|---|
join: | Any = “outer”, |
ignore_index: 重置索引 | bool = False, |
keys: | Any = None, |
levels: | Any = None, |
names: | Any = None, |
verify_integrity: | bool = False, |
sort: | bool = False, |
copy | : bool = True |
案例
两张表合并
basic=pd.concat([basic,basic_i],axis=0,ignore_index=True)
第一行与最后一行拼接
pd.concat([df[:1], df[-2:-1]])
利用高阶函数处理数据
Thinking: apply和map的区别是什么?
• apply 用在dataframe上,用于对row或者 column进行计算
• applymap 用于dataframe上,是元素级别的操 作
• map ,是python自带的,用于series上,是元 素级别的操
apply
自由度非常高的函数,使 用频率高
调用自定义函数对数据进行处理
df['sum'] = df[var_name].apply(np.sum,axis = 0) #相当于计算每列的总和
df['sum'] = df[var_name].apply(np.sum,axis=1) # 相当于计算每行的总和
定义个函数
def double_df(x):
return 2*x
df1[u'语文'] = df1[u'语文'].apply(double_df)
df2['user_id']=df2['user_id'].apply(lambdax:x.replace(x[1:3],'**'))
map
专门用来映射
字典
df2['sex']=df2['gender'].map({
'0':'girl','1':'boy','2':'unkonwn'})
自定函数
df2['sex']=df2['gender'].map(sex_set)
数据展示 | 两行代码要加载打印语句的前面,否则没有效果 pd.set_option | pd.set_option(‘display.max_columns’,None)#显示完整的列 pd.set_option(‘display.max_rows’,None)#显示完整的行 |
---|---|---|
版本 | pd.version | |
explod | DataFrame.explode(self, column: Union[str, Tuple]) 参数作用: column :str或tuple |
what | 英文文档处理包 | import nltk |
---|---|---|
#分词 | nltk.word_tokenize(text) | word_list = nltk.word_tokenize(text) |
#标注单词的词性 | nltk.pos_tag(word_list) | nltk.pos_tag(word_list) |
#中文分词 | jieba.cut (text) | word_list = jieba.cut (text) |
---|---|---|