Python笔记


前言

想学会一门语言不是一朝一夕的事情,本文是按照业务数据分析师/商业分析师 的路线来讲 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(官方网站)就是可以便捷获取包且对包能够进行管理,同时对环境可以统一管理的发行版本。Anaconda包含了conda、Python在内的超过180个科学包及其依赖项。

Mac 版本只有一个 Navigator 导航。数 据分析最常用的程序叫 Jupyter,以前被称为 IPython Notebook,是一个交互式的 笔记本,能快速创建程序,支持实时代码、可视化和 Markdown 语言。 点击 Jupyter 进入,它会自动创建一个本地环境 localhost。

特点

  • 开源
  • 安装过程简单
  • 高性能使用Python和R语言
  • 免费的社区支持

适用平台

Anaconda可以在以下系统平台中安装和使用:

  • Windows
  • macOS
  • Linux(x86 / Power8)

安装条件

  • 系统要求:32位或64位系统均可
  • 下载文件大小:约500MB
  • 所需空间大小:3GB空间大小(Miniconda仅需400MB空间即可)

安装步骤

1.1 macOS系统安装Anaconda

① 图形界面安装

  1. 前往官方下载页面下载。有两个版本可供选择:Python 3.6 和 Python 2.7,我下载的是前者。选择版之后点击“64-Bit Graphical Installer”进行下载。

  2. 完成下载之后,双击下载文件,在对话框中“Introduction”、“Read Me”、“License”部分可直接点击下一步。

  3. “Destination Select”部分选择“Install for me only”并点击下一步。

    注意:若有错误提示信息“You cannot install Anaconda in this location”则重新选择“Install for me only”并点击下一步。

  4. “Installation Type”部分,可以点击“Change Install Location”来改变安装位置。标准的安装路径是在用户的家目录下。在这一步我没有改变安装位置。若选择默认安装路径,则直接点击“Install”进行安装。

  5. 等待“Installation”部分结束,在“Summary”部分若看到“The installation was completed successfully.”则安装成功,直接点击“Close”关闭对话框。

  6. 在mac的Launchpad中可以找到名为“Anaconda-Navigator”的图标,点击打开。

  7. 若“Anaconda-Navigator”成功启动,则说明真正成功地安装了Anaconda;如果未成功,请务必仔细检查以上安装步骤。

  8. “Anaconda-Navigator”中已经包含“Jupyter Notebook”、“Jupyterlab”、“Qtconsole”和“Spyder”。(图中的“Rstudio”是我后来安装的,但它默认出现在“Anaconda-Navigator”的启动界面,只需要点击“Install”便可安装。)

  9. 完成安装。

1.2mac命令行安装

  1. 前往官方下载页面下载。有两个版本可供选择:Python 3.6 和 Python 2.7,我下载的是前者。选择版之后点击“64-Bit Command-Line Installer”进行下载。

  2. 完成下载之后,在mac的Launchpad中找到“其他”并打开“终端”。

    1. 安装Python 3.6:bash ~/Downloads/Anaconda3-5.0.1-MacOSX-x86_64.sh
    2. 安装Python 2.7:bash ~/Downloads/Anaconda2-5.0.1-MacOSX-x86_64.sh
  3. 注意:

    1. 首词bash也需要输入,无论是否用的Bash shell。
    2. 如果你的下载路径是自定义的,那么把该步骤路径中的~/Downloads替换成你自己的下载路径。
    3. 如果你将第1步下载的.sh文件重命名了,那么把该步骤路径中的Anaconda3-5.0.1-MacOSX-x86_64.sh或Anaconda2-5.0.1-MacOSX-x86_64.sh替换成你重命名后的文件名。
    4. 强烈建议:不要修改文件名。如果重命名,使用英文进行命名。
  4. 安装过程中,看到提示“In order to continue the installation process, please review the license agreement.”(“请浏览许可证协议以便继续安装。”),点击“Enter”查看“许可证协议”。

  5. 在“许可证协议”界面将屏幕滚动至底,输入“yes”表示同意许可证协议内容。然后进行下一步。

  6. 安装过程中,提示“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>”并且继续安装。安装过程大约需要几分钟的时间。

    1. 建议:直接接受默认安装路径。
  7. 安装器若提示“Do you wish the installer to prepend the Anaconda install location to PATH in your /home//.bash_profile ?”(“你希望安装器添加Anaconda安装路径在/home//.bash_profile文件中吗?”),建议输入“yes”。

    注意:

    1. 路径/home//.bash_profile中“”即进入到家目录后你的目录名。
    2. 如果输入“no”,则需要手动添加路径。添加export PATH="/ /bin:$PATH"在“.bashrc”或者“.bash_profile”中。其中,“ ”替换为你真实的Anaconda安装路径。
  8. 当看到“Thank you for installing Anaconda!”则说明已经成功完成安装。

  9. 关闭终端,然后再打开终端以使安装后的Anaconda启动。

  10. 验证安装结果。可选用以下任意一种方法:

    1. 在终端中输入命令condal list,如果Anaconda被成功安装,则会显示已经安装的包名和版本号。
    2. 在终端中输入python。这条命令将会启动Python交互界面,如果Anaconda被成功安装并且可以运行,则将会在Python版本号的右边显示“Anaconda custom (64-bit)”。退出Python交互界面则输入exit()或quit()即可。
    3. 在终端中输入anaconda-navigator。如果Anaconda被成功安装,则Anaconda Navigator的图形界面将会被启动。

1.3Windows系统安装Anaconda

  1. 前往官方下载页面下载。有两个版本可供选择:Python 3.6 和 Python 2.7,选择版之后根据自己操作系统的情况点击“64-Bit Graphical Installer”或“32-Bit Graphical Installer”进行下载。
  2. 完成下载之后,双击下载文件,启动安装程序。注意:
    1. 如果在安装过程中遇到任何问题,那么暂时地关闭杀毒软件,并在安装程序完成之后再打开。
    2. 如果在安装时选择了“为所有用户安装”,则卸载Anaconda然后重新安装,只为“我这个用户”安装。
    3. 选择“Next”。
  3. 阅读许可证协议条款,然后勾选“I Agree”并进行下一步。
  4. 除非是以管理员身份为所有用户安装,否则仅勾选“Just Me”并点击“Next”。
  5. 在“Choose Install Location”界面中选择安装Anaconda的目标路径,然后点击“Next”。注意:
    1. 目标路径中不能含有空格,同时不能是“unicode”编码。
    2. 除非被要求以管理员权限安装,否则不要以管理员身份安装。
  6. 在“Advanced Installation Options”中不要勾选“Add Anaconda to my PATH environment variable.”(“添加Anaconda至我的环境变量。”)。因为如果勾选,则将会影响其他程序的使用。如果使用Anaconda,则通过打开Anaconda Navigator或者在开始菜单中的“Anaconda Prompt”(类似macOS中的“终端”)中进行使用。
  7. 除非你打算使用多个版本的Anaconda或者多个版本的Python,否则便勾选“Register Anaconda as my default Python 3.6”
  8. 然后点击“Install”开始安装。如果想要查看安装细节,则可以点击“Show Details”。
  9. 点击“Next”。
  10. 进入“Thanks for installing Anaconda!”界面则意味着安装成功,点击“Finish”完成安装。注意:如果你不想了解“Anaconda云”和“Anaconda支持”,则可以不勾选“Learn more about Anaconda Cloud”和“Learn more about Anaconda Support”。
  11. 验证安装结果。可选以下任意方法:
    1. “开始 → Anaconda3(64-bit)→ Anaconda Navigator”,若可以成功启动Anaconda Navigator则说明安装成功。
    2. “开始 → Anaconda3(64-bit)→ 右键点击Anaconda Prompt → 以管理员身份运行”,在Anaconda Prompt中输入conda list,可以查看已经安装的包名和版本号。若结果可以正常显示,则说明安装成功。

1.4 Linux系统安装Anaconda

  1. 前往官方下载页面下载。有两个版本可供选择:Python 3.6 和 Python 2.7。
  2. 启动终端,在终端中输入命令md5sum /path/filename或sha256sum /path/filename注意:
    1. 将该步骤命令中的/path/filename替换为文件的实际下载路径和文件名。其中,path是路径,filename为文件名。
    2. 强烈建议:
      1. 路径和文件名中不要出现空格或其他特殊字符。
      2. 路径和文件名最好以英文命名,不要以中文或其他特殊字符命名。
  3. 根据Python版本的不同有选择性地在终端输入命令:
    1. Python 3.6:bash ~/Downloads/Anaconda3-5.0.1-Linux-x86_64.sh
    2. Python 2.7:bash ~/Downloads/Anaconda2-5.0.1-Linux-x86_64.sh
    3. 注意:
      1. 首词bash也需要输入,无论是否用的Bash shell。
      2. 如果你的下载路径是自定义的,那么把该步骤路径中的~/Downloads替换成你自己的下载路径。
  4. 除非被要求使用root权限,否则均选择“Install Anaconda as a user”。
  5. 安装过程中,看到提示“In order to continue the installation process, please review the license agreement.”(“请浏览许可证协议以便继续安装。”),点击“Enter”查看“许可证协议”。
  6. 在“许可证协议”界面将屏幕滚动至底,输入“yes”表示同意许可证协议内容。然后进行下一步。
  7. 安装过程中,提示“Press Enter to accept the default install location, CTRL-C to cancel the installation or specify an alternate installation directory.”(“按回车键确认安装路径,按’CTRL-C’取消安装或者指定安装目录。”)如果接受默认安装路径,则会显示“PREFIX=/home//anaconda<2 or 3>”并且继续安装。安装过程大约需要几分钟的时间。建议:直接接受默认安装路径。
    1. 安装器若提示“Do you wish the installer to prepend the Anaconda<2 or 3> install location to PATH in your /home//.bashrc ?”(“你希望安装器添加Anaconda安装路径在/home//.bashrc文件中吗?”),建议输入“yes”。注意:
      1. 路径/home//.bash_rc中“”即进入到家目录后你的目录名。
      2. 如果输入“no”,则需要手动添加路径,否则conda将无法正常运行。
  8. 当看到“Thank you for installing Anaconda<2 or 3>!”则说明已经成功完成安装。
  9. 关闭终端,然后再打开终端以使安装后的Anaconda启动。或者直接在终端中输入source ~/.bashrc也可完成启动。
  10. 验证安装结果。可选用以下任意一种方法:
    1. 在终端中输入命令condal list,如果Anaconda被成功安装,则会显示已经安装的包名和版本号。
    2. 在终端中输入python。这条命令将会启动Python交互界面,如果Anaconda被成功安装并且可以运行,则将会在Python版本号的右边显示“Anaconda custom (64-bit)”。退出Python交互界面则输入exit()或quit()即可。
    3. 在终端中输入anaconda-navigator。如果Anaconda被成功安装,则Anaconda Navigator将会被启动。

管理conda

  1. 写在前面

    接下来均是以命令行模式进行介绍,Windows用户请打开“Anaconda Prompt”;macOS和Linux用户请打开“Terminal”(“终端”)进行操作。

  2. 验证conda已被安装

    conda --version

    终端上将会以conda 版本号的形式显示当前安装conda的版本号。如:conda 3.11.0

    注意:如果出现错误信息,则需核实是否出现以下情况:

    1. 使用的用户是否是安装Anaconda时的账户。
    2. 是否在安装Anaconda之后重启了终端。
  3. 更新conda至最新版本

conda update conda

执行命令后,conda将会对版本进行比较并列出可以升级的版本。同时,也会告知用户其他相关包也会升级到相应版本。

当较新的版本可以用于升级时,终端会显示Proceed ([y]/n)?,此时输入y即可进行升级。

  1. 查看conda帮助信息

    conda --help 或 conda -h

  2. 卸载conda

    1. Linux 或 macOS

      rm -rf ~/anaconda2 或 rm -rf ~/anaconda3 。即删除Anaconda的安装目录。根据安装的Anaconda版本选择相应的卸载命令。

    2. Windows

    控制面板 → 添加或删除程序 → 选择“Python X.X (Anaconda)” → 点击“删除程序”

  3. 注意:

    1. Python X.X:即Python的版本,如:Python 3.6。
    2. Windows 10的删除有所不同。

管理环境

  1. 写在前面

    接下来均是以命令行模式进行介绍,Windows用户请打开“Anaconda Prompt”;macOS和Linux用户请打开“Terminal”(“终端”)进行操作。

  2. 创建新环境

    conda create --name <env_name> <package_names>注意:

    1. <env_name>即创建的环境名。建议以英文命名,且不加空格,名称两边不加尖括号“<>”。
    2. <package_names>即安装在环境中的包名。名称两边不加尖括号“<>”。
  3. 如果要安装指定的版本号,则只需要在包名后面以=和版本号的形式执行。如:conda create --name python2 python=2.7,即创建一个名为“python2”的环境,环境中安装版本为2.7的python。

  4. 如果要在新创建的环境中创建多个包,则直接在<package_names>后以空格隔开,添加多个包名即可。如:conda create -n python3 python=3.5 numpy pandas,即创建一个名为“python3”的环境,环境中安装版本为3.5的python,同时也安装了numpy和pandas。

    1. –name同样可以替换为-n。
    2. 提示:默认情况下,新创建的环境将会被保存在/Users/<user_name>/anaconda3/env目录下,其中,<user_name>为当前用户的用户名。
  5. 切换环境

    ① Linux 或 macOS

    source activate <env_name>

    ② Windows

    activate <env_name>

    ③ 提示

    1. 如果创建环境后安装Python时没有指定Python的版本,那么将会安装与Anaconda版本相同的Python版本,即如果安装Anaconda第2版,则会自动安装Python 2.x;如果安装Anaconda第3版,则会自动安装Python 3.x。
    2. 当成功切换环境之后,在该行行首将以“(env_name)”或“[env_name]”开头。其中,“env_name”为切换到的环境名。如:在macOS系统中执行source active python2,即切换至名为“python2”的环境,则行首将会以(python2)开头。
  6. 退出环境至root

    ① Linux 或 macOS

    source deactivate

    ② Windows

    deactivate

    ③ 提示

    当执行退出当前环境,回到root环境命令后,原本行首以“(env_name)”或“[env_name]”开头的字符将不再显示。

  7. 显示已创建环境

    conda info --envs 或

    conda info -e或 conda env list 结果中星号“*”所在行即为当前所在环境。macOS系统中默认创建的环境名为“base”。

  8. 复制环境

    conda create --name <new_env_name> --clone <copied_env_name>注意:

    1. <copied_env_name>即为被复制/克隆环境名。环境名两边不加尖括号“<>”。
    2. <new_env_name>即为复制之后新环境的名称。环境名两边不加尖括号“<>”。
    3. 如:conda create --name py2 --clone python2,即为克隆名为“python2”的环境,克隆后的新环境名为“py2”。此时,环境中将同时存在“python2”和“py2”环境,且两个环境的配置相同。
  9. 删除环境

    conda remove --name <env_name> --all

  • 注意:<env_name>为被删除环境的名称。环境名两边不加尖括号“<>”。

管理包

  1. 查找可供安装的包版本

    ① 精确查找

    conda search --full-name <package_full_name> 注意:

    1. –full-name为精确查找的参数。

    2. <package_full_name>是被查找包的全名。包名两边不加尖括号“<>”。

      例如:conda search --full-name python即查找全名为“python”的包有哪些版本可供安装。

  2. 模糊查找

    conda search 注意:

    1. 是查找含有此字段的包名。此字段两边不加尖括号“<>”。

      例如:conda search py即查找含有“py”字段的包,有哪些版本可供安装。

  3. 获取当前环境中已安装的包信息

    conda list 。执行上述命令后将在终端显示当前环境已安装包的包名及其版本号。

  4. 安装包

    ① 在指定环境中安装包

    conda install --name <env_name> <package_name> 注意:

    1. <env_name>即将包安装的指定环境名。环境名两边不加尖括号“<>”。

    2. <package_name>即要安装的包名。包名两边不加尖括号“<>”。

      例如:conda install --name python2 pandas即在名为“python2”的环境中安装pandas包。

    ② 在当前环境中安装包

    conda install <package_name> 注意:

    1. <package_name>即要安装的包名。包名两边不加尖括号“<>”。

    2. 执行命令后在当前环境中安装包。

      例如:conda install pandas即在当前环境中安装pandas包。

    ③ 使用pip安装包

    使用场景当使用conda install无法进行安装时,可以使用pip进行安装。例如:see包。→ 命令pip install <package_name> 注意:<package_name>为指定安装包的名称。包名两边不加尖括号“<>”。 如:pip install see即安装see包。注意

    1. pip只是包管理器,无法对环境进行管理。因此如果想在指定环境中使用pip进行安装包,则需要先切换到指定环境中,再使用pip命令安装包。
    2. pip无法更新python,因为pip并不将python视为包。
    3. pip可以安装一些conda无法安装的包;conda也可以安装一些pip无法安装的包。因此当使用一种命令无法安装包时,可以尝试用另一种命令。

    ④ 从Anaconda.org安装包

    1. 使用场景当使用conda install无法进行安装时,可以考虑从Anaconda.org中获取安装包的命令,并进行安装。 注意
      1. 从Anaconda.org安装包时,无需注册。
      2. 在当前环境中安装来自于Anaconda.org的包时,需要通过输入要安装的包在Anaconda.org中的路径作为获取途径(channel)。查询路径的方式如下:
    2. 在浏览器中输入:http://anaconda.org,或直接点击Anaconda.org
    3. 在新页面“Anaconda Cloud”的上方搜索框中输入要安装的包名,然后点击右边“放大镜”标志。
    4. 搜索结果中有数以千计的包可供选择,此时点击“Downloads”可根据下载量进行排序,最上面的为下载最多的包。(图中以搜索bottleneck包为例)
    5. 选择满足需求的包或下载量最多的包,点击包名。
    6. 复制“To install this package with conda run:”下方的命令,并粘贴在终端中执行。
    7. 完成安装。
  5. 卸载包

    ① 卸载指定环境中的包

    conda remove --name <env_name> <package_name> 注意:

    1. <env_name>即卸载包所在指定环境的名称。环境名两边不加尖括号“<>”。
    2. <package_name>即要卸载包的名称。包名两边不加尖括号“<>”。 例如:conda remove --name python2 pandas即卸载名为“python2”中的pandas包。

    ② 卸载当前环境中的包

    conda remove <package_name> 注意:

    1. <package_name>即要卸载包的名称。包名两边不加尖括号“<>”。
    2. 执行命令后即在当前环境中卸载指定包。例如:conda remove pandas即在当前环境中卸载pandas包。
  6. 更新包

    1. 更新所有包 conda update --all 或 conda upgrade --all

      1. 建议:在安装Anaconda之后执行上述命令更新Anaconda中的所有包至最新版本,便于使用。
    2. 更新指定包

      conda update <package_name>或 conda upgrade <package_name>

      注意:

      1. <package_name>为指定更新的包名。包名两边不加尖括号“<>”。
      2. 更新多个指定包,则包名以空格隔开,向后排列。如:conda update pandas numpy matplotlib即更新pandas、numpy、matplotlib包。

参考资料

  1. 知乎“初学python者自学anaconda的正确姿势是什么??”猴子的回答
  2. Anaconda Cheat Sheet
  3. Anaconda官方网站
  4. conda官方网站
  5. pip维基百科
  6. pip官方网站
  7. YouTube视频:Pip vs Conda: Differences and Comparisons
  8. virtualenv官方网站
  9. macOS系统安装Anaconda的官方教程
  10. Windows系统安装Anaconda的官方教程
  11. Linux系统安装Anaconda的官方教程
  12. Conda Official User Guide

Jupyter

灰色框是输入程序的地方,回车是换行,shift+回车执 行灰色区域的代码,它的结果会直接在下面空白处出现。这就是 Jupyter 交互式 的强大地方,将 Python 脚本分成片段式运行,尤其适合数据分析的摸索调整工 作

  1. 按tab键查看提示信息或者补全命令
  2. 在一个库、方法或变量前加上 ?,就可以获得它的一个快速语法说明
  3. 使用分号可以阻止该行函数的结果输出

Pycharm

Pycharm安装

用community版就可以;了解PyCharm的界面布局; 设置PyCharm的解释器 ; 调整PyCharm的界面主题与样式

PyCharm安装使用教程

macOS Mojave安装PyCharm 2018.x 最新版

Pycharm 解释器

pyCharm 快速上手指南

pyCharm 快捷键

PyCharm项目

PyCharm采用“项目(Project)”的方式管理源代码;一个项目通常就是一个完整的程序,包含多个源代码文件 ; 通常项目是以目录的方式保存。

快捷键

winmac
快速注释-块注释 来自注释 ctrl+/
格式化代码ctrl+alt+L
运行shift+ctrl+f10
复制行ctrl+d
调试
开始调试shift+alt+f9
逐行执行F7
停止调试ctrl + f2
调节格式alt + enter
快速查看函数的格式按住ctrl键,将鼠标放到函数上,就会显示函数信息,点击进去可以查看函数源码。

pip

  1. pip是用于安装和管理软件包的包管理器。

    pip名称的由来:pip采用的是递归缩写进行命名的。其名字被普遍认为来源于2处:

    “Pip installs Packages”(“pip安装包”)

    “Pip installs Python”(“pip安装Python”)

  2. pip编写语言:仅适用于Python

  3. Python中默认安装的版本:

    Python 2.7.9及后续版本:默认安装,命令为pip

    Python 3.4及后续版本:默认安装,命令为pip3

  4. 特点

    • 不一定会展示所需其他依赖包。
    • 安装包时或许会直接忽略依赖项而安装,仅在结果中提示错误
    • 维护多个环境难度较大。
    • 在系统自带Python中包的**更新/回退版本/卸载将影响其他程序。

虚拟环境 virtualenv

  1. 虚拟环境

    python 的虚拟环境可以为一个 python 项目提供独立的解释环境、依赖包等资源,既能够很好的隔离不同项目使用不同 python 版本带来的冲突,而且还能方便项目的发布。

    1. 解决问题:
      1. 当一个程序需要使用Python 2.7版本,而另一个程序需要使用Python 3.6版本,如何同时使用这两个程序?
      2. 如果将所有程序都安装在系统下的默认路径,如:/usr/lib/python2.7/site-packages,当不小心升级了本不该升级的程序时,将会对其他的程序造成影响。
      3. 如果想要安装程序并在程序运行时对其库或库的版本进行修改,都会导致程序的中断。
      4. 在共享主机时,无法在全局site-packages目录中安装包。
  2. virtualenv

    virtualenv可用于创建独立的 Python 环境,它会创建一个包含项目所必须要的执行文件。virtualenv将会为它自己的安装目录创建一个环境,这并不与其他virtualenv环境共享库;同时也可以选择性地不连接已安装的全局库

    1. 安装 virtualenv**
      • pip install virtualenv
  3. pycharm配置本地python虚拟环境

    1. PyCharm默认为虚拟环境

配置环境变量

配置环境变量-MAC

mac安装python3.7,配置环境变量。因mac自带python2.7环境,平时用的比较多的是python3.7,下面将安装及配置过程需要注意,避免这些坑。

  1. 安装软件包python3.7.pkg

  2. 进入终端,配置Python3环境变量

    1. open ~/.bash_profile

    2. 在文件末尾添加:

      export PATH=${PATH}:/Library/Frameworks/Python.framework/Versions/3.7/bin

      alias python="/Library/Frameworks/Python.framework/Versions/3.7/bin/python3.7"

    3. 让文件生效

      source ~/.bash_profile

    4. 进入终端,检查python版本

      python -v

配置环境变量-WIN

  1. 配置环境变量

    1. 快捷键ctrl + R 输入cmd进入命令行界面

    2. 命令行中输入python,可以看到已经进入了python环境。

      在这个步骤中,如果输入python提示命令未找到,说明环境变量配置失败。我们开始来配置环境变量。

  2. 配置环境变量:

    方法一:使用命令行配置。

    在cmd下输入:path=%path%;后面加上python安装路径。按enter回车即可。

    方法二:使用图形界面配置。

    1. 桌面我的计算机,右键选择属性

    2. 属性里面选择高级,点下面的环境变量

    3. 在系统变量值中找到“path”,在系统变量值中输入python的安装路径。(记得先加;分号隔开)配置完成之后确定退出。

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FiWmAzaR-1614984312160)(/Users/wu/Library/Application Support/typora-user-images/image-20210123215459993.png)]

    4. 再次打开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. 交互式

    1. 定义:在命令行输入指令,回车即可得到结果。

    2. 步骤:

      1. 打开终端
      2. 输入:python3
      3. 输入: print(“Hello World”)
      4. 退出:exit()
  2. 文件式

    1. 定义:将指令编写到.py文件中,可以重复运行程序。
       2. 步骤:
                 1. 创建文件:/home/tarena/1902/month01/day01/hello.py
              2. 打开终端进入指定目录 cd /1902/month01/day01
              3. 运行python程序  python3 hello.py
    

Python 版本

建议 3.0 以上,不要选择 2.7 的版本,否则你会被无尽的中文编码问 题困扰。

2.7安装

3.8帮助文档

python2和 python3区别?列举5个

  1. Python3使用 print必须要以小括号包裹打印内容,比如 print(h)Python2既可以使用带小括号的方式,也可以使用一个空格来分隔打印内容,比如 print"hi
  2. python2 range(1,10)返回列表, python3中返回迭代器,节约内存
  3. python2中使用asci编码, python中使用utf-8编码
  4. python2中 unicode表示字符串序列,str表示字节序列
    python3中st表示字符串序列,byte表示字节序列
  5. python2中为正常显示中文,引入 coding声明, python3中不需要
  6. python2中是 raw input()函数, python3中是 input(函数

程序调整Debug

  1. 调试目的

    理解程序执行过程、排除逻辑错误(不是Error)

  2. 方式

    pycharm:

    加断点(程序运行到本行停止,没有执行本行)

    开始调试shift+alt+f9

    逐行执行 F7

    停止调试ctrl + f2

GIL全局解释器锁

GIL是 python的全局解释器锁,进程中假如有多个线程运行,一个线程在运python程序的时候会霸占 python解释器(加了一把锁即G),使该进程内的其他线程无法运行,等该线程运行完后其他线程才能运行。如果线程运行过程中遇到耗时操作解释器锁解开,使其他线程运行。所以在多线程中,线程的运行仍是有先后顺序的,并不是同时进行。多进程中因为每个进程都能被系统分配资源,相当于每个进程有了一个 python解释器所以多进程可以实现多个进程的同时运行,缺点是进程系统资源开销大

提高python运行效率的方法?

  1. 使用生成器,因为可以节约大量内存
  2. 循环代码优化,避免过多重复代码的执
  3. 核心模块用 Cthon PyPy等,提高效率
  4. 多进程、多线程、协程
  5. 多个elf条件判断,可以把最有可能先发生的条件放到前面写,这样可以减少程序判断的次数,提高效率

异常

什么是异常?

异常即是一个事件,该事件会在程序执行过程中发生,影响了程序的正常执行。

一般情况下,在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缩进错误
TabErrorTab 和空格混用
SystemError一般的解释器系统错误
UnicodeErrorUnicode 相关的错误
UnicodeDecodeErrorUnicode 解码时的错误
UnicodeEncodeErrorUnicode 编码时错误
UnicodeTranslateErrorUnicode 转换时错误
Warning警告的基类
DeprecationWarning关于被弃用的特征的警告
FutureWarning关于构造将来语义会有改变的警告
OverflowWarning旧的关于自动提升为长整型(long)的警告
PendingDeprecationWarning关于特性将会被废弃的警告
RuntimeWarning可疑的运行时行为(runtime behavior)的警告
SyntaxWarning可疑的语法的警告
UserWarning用户代码生成的警告

自定义异常

通过创建一个新的异常类,程序可以命名它们自己的异常。异常应该是典型的继承自Exception类的自定义类**

异常处理try…except

  1. 捕捉异常可以使用try/except语句。

    try/except语句用来检测try语句块中的错误,从而让except语句捕获异常信息并处理。如果你不想在异常发生时结束你的程序,只需在try里捕获它。

  2. 异常的传递

    如果异常在产生的地方不被捕获,异常会一层层向外抛出,各层调用程序后的程序则不会执行。

  3. 语法:以下为简单的try…except…else的语法:

    try:
    <语句> #运行别的代码
    except <名字>:
    <语句> #如果在try部份引发了’name’异常
    except <名字>,<数据>:
    <语句> #如果引发了’name’异常,获得附加的数据
    else:
    <语句> #如果没有异常发生

  4. try的工作原理是

    1. 当开始一个try语句后,python就在当前程序的上下文中作标记,这样当异常出现时就可以回到这里,try子句先执行,接下来会发生什么依赖于执行时是否出现异常。
    2. 如果当try后的语句执行时发生异常,python就跳回到try并执行第一个匹配该异常的except子句,异常处理完毕,控制流就通过整个try语句(除非在处理异常时又引发新的异常)。
    3. 如果在try后的语句里发生了异常,却没有匹配的except子句,异常将被递交到上层的try,或者到程序的最上层(这样将结束程序,并打印默认的出错信息)。
    4. 如果在try子句执行时没有发生异常,python将执行else语句后的语句(如果有else的话),然后控制流通过整个try语句。
  5. 实例

下面是简单的例子,它打开一个文件,在该文件中的内容写入内容,但文件没有写入权限,发生了异常:

\#!/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: 没有找到文件或读取文件失败

  1. 拓展
    • 使用except而不带任何异常类型
    • 使用except而带多种异常类型
    • 使用多个except而带多种异常类型
    • try-finally 语句
    • 异常的参数

抛出异常 raise

  1. 定义:可以在程序的指定位置手动抛出一个异常,使用 raise 语句即可。

  2. 作用:我们从来都是想方设法地让程序正常运行,为什么还要手动设置异常呢?首先要分清楚程序发生异常和程序执行错误,它们完全是两码事,程序由于错误导致的运行异常,是需要程序员想办法解决的;但还有一些异常,是程序正常运行的结果,比如用 raise 手动引发的异常。引发的异常通常用 try except(else finally)异常处理结构来捕获并进行处理。

  3. raise 语句的基本语法格式为:

    raise [Exception [, args [, traceback]]]
    
    • Exception 是异常的类型(例如,NameError)参数标准异常中任一种
    • args 是自已提供的异常参数。
    • 最后一个参数是可选的(在实践中很少使用),如果存在,是跟踪异常对象。
    • 用 [] 括起来的为可选参数,其作用是指定抛出的异常名称,以及异常信息的相关描述。如果可选参数全部省略,则 raise 会把当前错误原样抛出;如果仅省略 (reason),则在抛出异常时,将不附带任何的异常描述信息。可以通过创建一个新的exception类来拥有自己的异常。
  4. raise 语句有如下三种常用的用法:

    1. raise:单独一个 raise。该语句引发当前上下文中捕获的异常(比如在 except 块中),或默认引发 RuntimeError 异常。

      如果你只想知道这是否抛出了一个异常,并不想去处理它,那么一个简单的 raise 语句就可以再次把它抛出。

      • 默认引发的是 RuntimeError 异常

      当在没有引发过异常的程序使用无参的 raise 语句时,它默认引发:RuntimeError 异常

    2. raise 异常类名称:raise 后带一个异常类名称,表示引发执行类型的异常。

    3. raise 异常类名称(描述信息):在引发指定类型的异常的同时,附带异常的描述信息。

遇到bug如何处理?

  1. 细节错误

    细节上的错误,通过 print()打印,能执行到 print()说明一般上面的代码没有问
    题,分段检测程序是否有问题,如果是js的话可以 alert或 console. log

  2. 第三方框架

    如果涉及一些第三方框架,会去查官方文档或者一些技术博客

  3. bug的管理

    对于bug的管理与归类总结,一般测试将测试出的bug用 teambin等bug管理工具进
    行记录,然后我们会一条一条进行修改,修改的过程也是理解业务逻辑和提高自己编程逻
    辑缜密性的方法,我也都会收藏做一些笔记记录

  4. 其他问题

    导包问题、城市定位多音字造成的显示错误问题

内置函数

68个内置函数综合整理为12大类。

数字相关

1. 数据类型

  • bool : 布尔型(True,False)
  • int : 整型(整数)
  • float : 浮点型(小数)
  • complex : 复数

2. 进制转换

  • bin() 将给的参数转换成二进制

  • otc() 将给的参数转换成八进制

  • hex() 将给的参数转换成十六进制

    print(bin(10)) # 二进制:0b1010
    
    print(hex(10)) # 十六进制:0xa
    
    print(oct(10)) # 八进制:0o12
    

3. 数学运算

  • 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
    

序列相关

1.列表和元组

  • 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)
    

2.相关内置函数

  • 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]
    

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饭'
    

4. 数据集合

  • 字典:dict 创建一个字典

  • 集合:set 创建一个集合4

    有去重和排序的功能,因为集合是无序不重复元素

  • frozenset() 创建一个冻结的集合,冻结的集合不能进行添加和删除操作。

5. 集合相关内置函数

  • 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)) #<zip object at 0x00000256CA6C7A88>
    
    for  el in zip(lst1, lst2, lst3):
      print(el)
    
    \# (1, '醉乡民谣', '美国')
    
    \# (2, '驴得水', '中国')
    
    \# (3, '放牛班的春天', '法国')
    
    \# (4, '美丽人生', '意大利')
    
    \# (5, '辩护人', '韩国')
    
    \# (6, '被嫌弃的松子的一生', '日本')
    
  • reduce

    • Reduce(fun,seq[,initial])

    • 按照指定的方法将序列中的元素缩减为一个值,最终是一个元素类型。

  • lamada

    1. 匿名函数.又称lambda表达式,用于处理简单业务的函数,不需要显式地定义函数,直接传入匿名函数。用匿名函数有个好处,因为函数没有名字,不必担心函数名冲突。

    2. 注意:

      1. 并非是一个代码块,没有函数名,只有一行代码
      2. 传入的参数可以有很多,
      3. 返回值只能由一个,不用写return,返回值就是该表达式的结果
    3. 案例

      以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** <lambda> 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))
      
      1. 匿名函数也是一个函数对象,也可以把匿名函数赋值给一个变量,再利用变量来调用该函数:

      2. 把匿名函数作为返回值返回,比如:

  • filter() 过滤 (lamda)

    1. 对(序列)可迭代对象进行过滤,返回一个迭代器对象。过滤条件为布尔类型的函数,过滤掉的元素是:执行函数结果为0,留下结果为1的函数。

    2. 注意:描述中可迭代对象和序列的描述,输出结果 时要确定对象类型,tumple/list,否返回的是迭代器所在的位置

    3. 语法: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) #<filter object at 0x000001CE3CA98AC8>
      
      print(list(l1)) #[1, 3, 5, 7, 9]
      
  • map()

    1. 会根据提供的函数对可迭代对象中的每一个元素进行映射. 分别去执行 function

      将传入的函数依次作用于列表中的的每一个元组,返回一个map对象。

    2. 语法 : 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]
      

和作用域相关

  • locals() 返回当前作用域中的名字
  • globals() 返回全局作用域中的名字
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() 生成数据

    • 左闭右开
    • python2返回列表, python3返回迭代器,节约内存
  • 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

文件操作相关

  • open() : 用于打开一个文件, 创建一个文件句柄
  • with():with方法帮我们实现了 finally中 f.close.打开文件在进行读写的时候可能会出现一些异常状况,如果按照常规的f.open写法,我们需要try, except; final!y,做异常判断,并且文件最终不管遇到什么情况,都要执行 finally ,f.close0关闭文件
    (当然还有其他自定义功能,有兴趣可以研究with方法源码)
f = open('file',mode='r',encoding='utf-8')
try:
  f.read()
except:
  pass
finally:
  f.close()

模块相关

  • __ import__() : 用于动态加载类和函数
# 让用户输入一个要导入的模块

**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 时显示的字符串。

查看内置属性

  • dir() : 查看对象的内置属性, 访问的是对象中的__dir__()方法
print(dir(tuple)) #查看元组的方法

语法结构

1.规范 PEP8

PEP8是 Python Enhancement Proposal 8的缩写,翻译过来就是 Python增强建议书,也就是Python编码规范。例如:缩进,注释,行限字数,每行之间的空行,空格的使用等

2.注释

对代码进行标注,增加可读性.

  1. 单行注释采用 # 开头

    注释可以在语句或表达式行末。实际的应用中会对代码本身注释,不执行进行调试

# 第一个注释
 print "Hello, Python!"; # 第二个注释
  1. 多行注释使用三个单引号(’’’)或三个双引号(""")。
''' 

这是多行注释,使用单引号。

这是多行注释,使用单引号。 这是多行注释,使用单引号。 

''' 

"""

这是多行注释,使用双引号。 

这是多行注释,使用双引号。 

这是多行注释,使用双引号。 

"""

3.转义字符

定义:可以改变原有字符含义的特殊字符

常用的:

\’ \” \””” \n

\t 水平制表格 \0 空字符 \

4.行和缩进

    • 物理行:程序员编写代码时的行。
    • 逻辑行:python解释器需要执行的指令。 建议一个物理行对应一个逻辑行。

    ​ 示例: print(“ok”); print(“no”) 一个物理行,两个逻辑行。

    • 隐式换行:所有括号的中的内容都可以换行。

      x = 1 + (2+ 3+

    • 显示换行:通过折行符 \ 换行

      x = 1 + 2+ 3 \

      +4

  1. python缩进来写模块。

    使用缩紧来控制类,函数以及其他逻辑判断。

    代码块中必须使用相同数目的行首缩进空格数。建议你在每个缩进层次使用 单个制表符两个空格四个空格 , 不能混用.

    没有严格缩进,在执行时错,IndentationError: unexpected indent 错如果是 IndentationError: unindent does not match any outer indentation level错误表明,你使用的缩进方式不一致,有的是 tab 键缩进,有的是空格缩进,改为一致即可。

  2. 多个语句构成代码组

    代码组:缩进相同的一组语句构成一个代码块。

    像if、while、def和class这样的复合语句,首行以关键字开始,以冒号( : )结束,该行之后的一行或多行代码构成代码组。

  3. 多行语句

    一般以新行作为为语句的结束符。可以使用斜杠( \)将一行的语句分为多行显示。

    1. 注释不能写在字符串内

    2. 换行字符和连结字符后不能有其他函数或者空格,本质上仍然是一段

    3. 有换行后需要有连结符

    4. 语句中包含[], {} 或 () 括号就不需要使用多行连接符。如下实例:

       days = ['Monday', 'Tuesday', 'Wednesday',
          'Thursday', 'Friday']
      
  4. 同一行显示多条语句

    import sys; x = 'w3cschool';
    
    

5. 函数

表示一个功能,制作函数的人叫做函数定义者,使用函数的人叫做函数调用者。

6. 变量variable

  1. 定义:关联一个对象的标识

    程序的作用就是用来处理数据,而变量就是用来保存的基本单位;为变量设置“值”的过程,称为“赋值”。

    变量存储在内存中的值。这就意味着在创建变量时会在内存中开辟一个空间。基于变量的数据类型,解释器会分配指定内存,并决定什么数据可以被存储在内存中。因此,变量可以指定不同的数据类型,这些变量可以存储整数,小数或字符。

  2. 变量语法

    变量名 = 表达式

    变量名1 = 变量名2 = 表达式

    变量名1,变量名2 =表达式1,表达式2

  3. 变量赋值

    1. 等号(=)用来给变量赋值。Python中的变量不需要声明,变量的赋值操作既是变量声明和定义的过程。一个变量可以通过赋值指向不同类型的对象。

    2. 等号(=)运算符左边是一个变量名,等号(=)运算符右边是存储在变量中的

      name = “毛主席” #文本

      salary = 1938.8 #数字

      is_weekend = True #布尔值

    3. 多个变量赋值

      1. Python允许你同时为多个变量赋值。例如: a = b = c = 1。以上实例,创建一个整型对象,值为1,三个变量被分配到相同的内存空间上。
      2. 可以为多个对象指定多个变量。例如:a, b, c = 1, 2, “john” 以上实例,两个整型对象1和2的分配给变量a和b,字符串对象"john"分配给变量c。
  4. 变量名称

    1. 要求:

      1. 必须为字母数或下划线,后面跟着字母,数字,下划线
      2. 所有单词小写,多个单词之间使用 _ 连接
      3. 见名知义
      4. 最好使用英文单词,不建议使用拼音;
      5. 长度最好不要超过20个字符,过长可是使用缩写;
      6. =右端留空格
      7. 不能数字开头
      8. 不能与python保留字重名
    2. 常见错误

      Python使用半角字符 ;大小写错误,Python大小写敏感;英文单词拼写错误

  5. Python标识符

    1. 有标识符可以包括英文、数字以及下划线(_),但不能以数字开头。

    2. 区分大小写的,所有Python的关键字只包含小写字母。

    3. 以下划线开头的标识符是有特殊意义的。

      以单下划线开头(_foo)的代表不能直接访问的类属性,需通过类提供的接口进行访问,不能用"from xxx import *"而导入;

    4. 以双下划线开头的代表类的私有成员;

      以双下划线开头和结尾的(foo)代表python里特殊方法专用的标识,如__init__()代表类的构造函数。

  6. Python保留字符

    下面的列表显示了在Python中的保留字。这些保留字不能用作常数或变数,或任何其他标识符名称。

    andexecnot
    assertfinallyor
    breakforpass
    classfromprint
    continueglobalraise
    defifreturn
    delimporttry
    elifinwhile
    elseiswith
    exceptlambdayield

数据类型

六个标准的数据类型,

数据结构:计算机存储数据、组织数据的容器。包含:数值型(int、bool、)、字符串str、列表list、元组Tuple、字典Dictionary、集合Set 、None:表示不存在的特殊对象; 作用:用来占位 a = None;变量解除绑定

可变与不可变数据类型

  1. 不可变数据类型:数值型、字符串型 string和元组 tuple
    不允许变量的值发生变化,如果改变了变量的值,相当于是新建了一个对象,而对于相的值的对象,在内存中则只有一个对象(地址),如下图:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tR6pyLko-1614984312164)(/Users/wu/Documents/image-20210201105951984.png)]

  2. 可变数据类型:列表list、集合set和字典dict
    允许变量的值发生变化,即如果对变量进行 append、+=等这种操作后,只是改变了变量的值,而不会新建一个对象,变量引用的对象的地址也不会变化,不过对于相同的值的不同对象,在内存中则会存在不同的对象,即每个对象都有自己的地址,相当于内存中对于同值的对象保存了多份,这里不存在引用计数,是实实在在的对象。

    image-20210201110347100

序列sequence

是指有序的队列,序列中的元素按照添加顺序排列,可以通过索引进行获取。

  1. 字符串(Str)
  2. 列表(list)
  3. 元组(Tupe)
  4. 数字序列( Range)

数据类型转换

将数据类型作为函数名即可

函数描述
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)将一个整数转换为一个十六进制字符串

1.数字-Numbers

  1. 类别

    int整型boolfloat浮点型complex 复数
    1e6 (10的6次)true0.03.14j
    100flase15.2045.j
    -786-21.99.322e-36j
    08032.3+e18.876j
    -0490-90.-.6545+0J
    -0x260-32.54e1003e+26J
    0x6970.2-E124.53e-7j
  2. 创建

    1. 当你指定一个值时,Number对象就会被创建

    2. 数值的除法(/)总是返回一个浮点数,要获取整数使用//操作符。在混合计算时,Pyhton会把整型转换成为浮点数。

  3. 删除

    使用del语句删除一些对象引用

    您可以通过使用del语句删除单个或多个对象。例如:

    del var
    del var_a, var_b

2. 字符串-String

  1. 定义

    一系列字符(数字、字母、下划线)组成的不可变序列容器,存储的是字符编码值。

    str用单引号(’ ')或双引号(" ")括起来,s=“a1a2···an”(n>=0)、

  2. 转意 \ , ,r可以使得斜杆无效

    s='yeshedon\'t' # 斜杆后的单引号转意
    
    print(s)
    
    s1=r'yshedon\'t'
    
    print(s1)
    
    '''
    
    yeshedon't
    
    yshedon\'t
    
    '''
    
  3. 续行符 反斜杠 / 。可以作为,表示下一行是上一行的延续。还可以使用"""…"""或者’’’…’’'跨越多行。三个双引号 或者单引号

    str_number = '匪警[110],火警[119],急救中心[120],' \
    
          '道路交通事故报警[122],水上求救专用电话[12395],' \
    
          '天气预报[12121],报时服务[12117],森林火警[12119],电力服务[95598],' \
    
          '红十字会急救台[999],公安短信报警[12110],通用紧急求救[112],' \
    
        '信产部IP/网站备案[010-66411166]'
    
    print(str_number)
    
  4. 字符串拼接

    +运算符连接在一起,用*运算符重复。

    print(str*2)#输出字符串两次

  5. 制表符与换行符

    制表符是指增加字符的缩进,在字符串中使用\t

    换行符是指为字符串换行输出,在字符串中使用\n

  6. str.join(序列)

  7. 删除

    1. 空白
    ' python''python'是不同的字符串 ,第一个前面有空格
    
    str.lstrip() 删除左侧空白 
    
    str.rstrip() 删除右侧空白 
    
    str.strip() 删除两端空白
    
    space_str='helloworld'
    
    print(space_str)
    
  8. 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)
    
  9. 查找

    1. 索引查找:字符串有两种索引方式,从左往右以0开始,从右往左以-1开始。取一段,变量[头下标:尾下标]

      print('str')#输出完整字符串
      
      print(str[0])#输出字符串中的第一个字符
      
      print(str[2:5])#输出字符串中第三个至第五个之间的字符串
      
      print(str[2:])#输出从第三个字符开始的字符串
      
    2. 获取字符串的长度

      len、

      lstr=len(space_str)
      
      print(lstr)
      
    3. 内容查找find :对字符串的进行遍历,存在返回所在位置的索引,不存在则返回

    4. 其他函数

      函数名称说明
      contains()返回表示各str是否含有指定模式的字符串
      replace()替换字符串。
      lower()返回字符串的副本,其中所有字母都转换为小写。
      upper()返回字符串的副本,其中所有字母都转换为大写。
      split()分割字符串,返回字符串中的单词列表
      info_list = info.split(’,’)
      strip()删除前导和后置空格。
      join()返回一个字符串,该字符串是给定序列中所有字符串的连接。
      str.title()每个单词首字母大写
      str.swapcase()大小写互换
      rjust() 方法将字符串靠右, 并在左边填充空格
      ljust()
      center()
      ‘end’连接上下行的内容
      zfill()数字的左边填充 0

3. 列表list

  1. 定义

    由一系列变量组成的可变序列容器。在内存中按照顺序序列排列和存储,动态变化存储;内存允许扩展,适合存储高频变化的词。

    1. 写在方括号之间,元素用逗号隔开,
    2. 元素的类型可以不相同,
    3. 可以包含可变的对象、复合数据类型,它支持:字符,数字,字符串、列表(所谓嵌套),
  2. 注:

    1. 列表实用效率低

      在表达结构化的数据方面不足:结构化数据指代有明确属性、规则的数据。

  3. 基础操作

    1. 创建:[元素] list(可迭代对象)

    2. 增加:insert append

    3. 删除:remove del

    4. 修改:列表名[索引] = 数值

      1. 使用+操作符进行拼接
    5. 查:索引 切片

      索引有正序和倒叙两种。[]:取值左闭右开

      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]
      # []
      
      
  4. 相关函数介绍

    方法描述
    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()
  5. 字符串VS列表

    1. 列表和字符串都是序列,元素之间有先后顺序。

    2. 列表和字符串都属于可迭代对象。

    3. 字符串不可变,列表可变。

    4. 字符串中每个元素存储字符,而列表可以存储任意类型对象。

    5. 转化

      1. Join :将多个字符串拼接为一个列表。

        result = “连接符”.join(列表)

      2. Split: 将一个字符串拆分为多个列表。

        列表 = “a-b-c-d”.split(“分隔符”)

  6. 列表推导式

    1. 作用:使用简易方法,将可迭代对象转生成为列表。

    2. 语法:

      1. 变量 = [表达式 for 变量 in 可迭代对象]

      2. 变量 = [表达式 for 变量 in 可迭代对象 if 条件]

        如果将 表达式 换为条件 返回 bool值

    3. 示例:

      \# 传统生成列表写法
      
      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]
      

4. 元组tuple

  1. 定义

    由一系列变量组成的不可变序列容器。元组,可以看做是不可变得列表,元组用"()"标识。内部元素用逗号隔开。可以包含可变的对象,比如list列表 构造包含0个或1个元素的tuple是个特殊的问题,所以有一些额外的语法规则。读取方式类似列表

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6qREagQ3-1614984312165)(/Users/wu/Documents/image-20210125183137837.png)]

  2. 作用

    元组与列表都可以存储一系列变量。

    列表会预留内存空间,所以可以增加。

    元组会按需分配内存,建议变量数据固定时使用元组,因为通常占用空间小。

  3. 基础操作

    1. 创建

      1. 空元组 tup1 = ()

      2. 创建有元素的元组:(元素) tuple(可迭代对象)

        **一个元素,需要在元素后添加逗号,**否则为字符串 tup2 = (20,)

        print(type((1,)),type((1)),type(('1')))
        # <class 'tuple'> <class 'int'> <class 'str'>
        
    2. 获取元素:索引 切片

    3. 删:不能删除,相当于只读列表。

    4. 其他

      1. 支持运算符 ,+拼接 * 重复

      2. 函数

        方法及描述实例
        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’)
    5. 案例

      # 可以没有括号
      t = 12345, 54321, 'hello!'
      print(type(t))
      # <class 'tuple'>
      ## 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
      '''
      
  4. 列表与元组的区别

    元组列表
    内容不可变内容允许扩展
    创建后固定不变内存存储动态变化
    效率最高效率较低
    用于保存稳定不变的数据运行时数据需要变更时使用
    保存国家名、元素周期表保存天气数据、股市数据

5. 字典dic

  1. 定义:Dictionary ,无序键—值对组成的可变映射容器。

    • 是一种映射类型(mapping type)适合表达可结构化的数据:(键 : 值)对集合,

    • 键必须是唯一且不可变的,如字符串,数字或元组;

      序列是以连续的整数为索引,字典以关键字为索引,所以可以是任意不可变类型,可以用数字,字符串或元组充当,而用列表就不行。如果同一个键被赋值两次,后一个值会被记住。

    • 值没有限制:字典可变容器模型,且可存储任意类型对象。

    • 映射(哈希算法):通过键对应值,每条记录无序。

    ​ 字典也被称为哈希(hash),对应散列值。散列值是某一个数据的唯一标识,哈希值是字典的底层实现:(类似于利用伪随机数建)

    ​ [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uJMvVzu7-1614984312166)(/Users/wu/Documents/image-20210125183736122.png)]

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hXFehCGr-1614984312167)(/Users/wu/Documents/image-20210125183223197.png)]

  2. 基础操作

    1. 创建字典:

      1. 一对大括号创建一个空的字典:{}

        {键1:值1,键2:值2}

    2. 添加/修改:

    ​ 字典[键] = 表达式

    说明:键不存在则创建,键存在则修改。

    1. 获取记录:

    ​ 字典[键] 说明:如果不存在键,则错误。

    1. 删除:

      1. 删除键 del 字典[键]
      2. dict.pop(’’)
      3. dict.popitem : delete the last tuple and out put
    2. 字典合并 dict1.update(dict2)

    3. 排序:

      sorted(dic):默认按照字典的键排序 返回键列表

      sorted(dic.items()):按键排序,返回键值元组对列表

    4. 其他函数

      函数及描述
      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()
    5. 案例

      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)
      

6.集合set

  1. 定义: 由一系列不重复的变量组成的可变映射容器。集合(set)是一个无序不重复元素的集。相当于只有键没有值的字典,元素都可以看作是key。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QEniANUh-1614984312168)(/Users/wu/Documents/image-20210125202651766.png)]

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ev1gsykD-1614984312169)(/Users/wu/Documents/image-20210125202609775.png)]

  2. 特点:

    1. 元素是无序的,运行时返回的顺序不一定,不支持按索引提取
    2. 元素不可重复
    3. 元素是可变的
    4. 允许进行集合数学操作:交并补
    5. 是分散储存
  3. 础操作

    1. 创建空集合:set()

      1. 固定集合:不可变的集合。

        1. 创建空集合:frozenset()
        2. 创建具有默认值的集合:frozenset (可迭代对象)
      2. 一般集合

        1. 可以使用大括号 或者 set()函数创建set集合,注意:创建一个空集合必须用 set() 而不是 { },因为{ }是用来创建一个空字典。
    2. 创建具有默认值的集合:{元素1,元素2}

      set(可迭代对象)

    3. 添加:add 、upset

    4. 删除:

      set.remove()#当元素不存时会报错

      Set.discard() #当元素不存时自动跳过

    5. 运算

      交集、并集、补集、对称补集、子集、超集

    6. #遍历

      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)

    7. 案例

      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语言支持以下类型的运算符:

  1. 算术运算符
  2. 比较(关系)运算符
  3. 赋值运算符
  4. 逻辑运算符
  5. 位运算符
  6. 成员运算符
  7. 身份运算符
  8. 运算符优先级

算术运算符

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

  1. 短路逻辑

    如果and前面的表达式结果为false,后面的表达式不再执行;如果or前面的表达式结果为True,后面的表达式不再执行

    建议:将耗时的判断尽量放在后面

    以下假设变量 a 为 10, b为 20:

    运算符逻辑表达式描述实例
    andx and y布尔"与" - 如果 x 为 False,x and y 返回 False,否则它返回 y 的计算值。(a and b) 返回 20。
    orx or y布尔"或" - 如果 x 是 True,它返回 x的值,否则它返回 y 的计算值。(a or b) 返回 10。
    notnot 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 )#纯数字比较。

身份运算符

身份运算符用于比较两个对象的存储单元

运算符描述实例
isis是判断两个标识符是不是引用自一个对象x is y, 如果 id(x) 等于 id(y) , is 返回结果 1
is notis not是判断两个标识符是不是引用自不同对象x is not y, 如果 id(x) 不等于 id(y). is not 返回结果 1

运算符优先级

以下表格列出了从最高到最低优先级的所有运算符:

运算符描述
**指数 (最高优先级)
~ + -按位翻转, 一元加号和减号 (最后两个的方法名为 +@ 和 -@)
* / % //乘,除,取模和取整除
+ -加法减法
>> <<右移,左移运算符
&位 ‘AND’
^ |位运算符
<= < > >=比较运算符
<> == !=等于运算符
= %= /= //= -= += *= **=赋值运算符
is is not身份运算符
in not in成员运算符
not or and逻辑运算符

输入和输出

输入input函数:

将用户输入的字符串保存到变量 接收用户输入 。由于是字符串类型,所以不能够用于计算需要转变变量的类型。

语法格式:变量 = input(“提示信息”) 示例:

mobile = input("请输入您的手机号")
couter=int(num)*20

输出

Python两种输出值的方式: 表达式语句和 print() 函数。(第三种方式是使用文件对象的 write() 方法; 标准输出文件可以用 sys.stdout 引用

1.% 字符串格式化输出

  1. 定义:%操作符生成一定格式的字符串。因为 str.format() 比较新的函数, 大多数的 Python 代码仍然使用 % 操作符。但是因为这种旧式的格式化最终会从该语言中移除, 应该更多的使用 str.format().

  2. 语法:” …%格式….” %(变量)

  3. 格式:

    %[- + 0 宽度.精度]类型码

    - : 左对齐(默认就是右对齐)

    +:显示正号

    0:左侧空白位置补零

    宽度:整个数据输出的宽度(字符大小)

    精度:保留小数点后多少位

    类型码:%s-字符串、%d整数、%f-浮点数来格式化字符串

  4. 定义

    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.
    

2.format() 函数

  1. 基本使用如下,占位符:配合{}大括号:,其里面的字符将会被 format() 中的参数替换:
print('We are the {} who say "{}!"'.format('knights', 'Ni'))
We are the knights who say "Ni!"

  1. fomat配合索引

    1. 数字索引

      在括号中的数字用于指向传入对象在 format() 中的位置,位置可以打乱如下所示:

      for x in range(1,11):
      print('{0:2d}{1:3d}{2:4d}'.format(x,x*x,x*x*x))
      
    2. 关键字索引,如果在 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))
      
    3. 关键词和数字混合索引:关键词位置要对应

      print('Thestoryof{1},{0},and{other}.'.format('Bill','Manfred',other='Georg'))
      
  2. 格式

    1. 数字格式化

      注意’:'格式化输出数字时,需要在{}添加:作为前缀,之后写上数字的格式

      示例:
      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
      
    2. ‘!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.
    
    1. 在 ‘:’ 后传入一个整数, 可以保证该域至少有这么多的宽度。 用于美化表格时很有用。

      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
      

流程控制语句

执行顺序

顺序执行:按照条件的编写顺序。

分支语句:条件选择执行

循环语句:循环执行。

控制语句

  1. pass语句
  2. 条件语句
  3. 循环语句
  4. 跳转语句

条件语句 --if else

​ Python条件语句是通过一条或多条语句的执行结果(True或者False)来决定执行的代码块。Python程序语言指定任何非0和非空(null)值为true,0 或者 null为false。

  1. if else

    1. 作用:让程序根据条件有选择性的执行语句。

    2. 语法:

      if 真值表达式: 满足条件执行的语句 else: 不满足条件执行的语句块

      if 真值表达式1: 满足条件1执行的语句块 elif 真值表达式2:满足条件2执行的语句 else:以上条件都不满足执行的语句块

  2. 说明:

    elif 字句可以有0个或者多个。

    else 字句最多有1个,只能放在最后。

  3. 条件表达式

    作用:可以选择性的为变量进行赋值

    语法: 变量 = 满足条件的结果 if 条件 else 不满足条件的结果

  4. 语句中经常会用到运算法:

    if语句:比较运算法、成员运算符、身份运算符

    else:赋值运算法

  5. 注意:

    1. 每个条件后面要使用冒号(:),表示接下来是满足条件后要执行的语句块。

    2. 使用缩进来划分语句块,相同缩进数的语句在一起组成一个语句块。

    3. 在Python中没有switch – case语句。

      由于 python 并不支持 switch 语句,所以多个条件判断,只能用 elif 来实现,如果判断需要多个条件需同时判断时,可以使用 or (或),表示两个条件有一个成立时判断条件成功;使用 and (与)时,表示只有两个条件同时成立的情况下,判断条件才成功。当if有多个条件时可使用括号来区分判断的先后顺序,括号中的判断优先执行,此外 and 和 or 的优先级低于>(大于)、<(小于)等判断符号,即大于和小于在没有括号的情况下会比与或要优先判断

  6. if else 简单的写法 4种:

    但是对于数据分析来说,代码的易读性优于简洁性

    1. 传统

      a, b, c = 1, 2, 3
      if a>b:
        c = a
      else:
        c = b
      
    2. 一行表达式,为真时放if前

      c = a if a>b else b
      
    3. 二维列表,利用大小判断的0,1当作索引

      c= [b, a][a > b]
      
    4. 第四种最有意思了,利用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
      
  7. 判断语句为None

    1. 当判断语句为None时 执行 else 。等同于 条件为false,案例:

      a= None
      b=2
      c=3
      c = a if a else b
      print(c)
      #执行结果:2
      

循环语句-- for while

  1. for循环和while循环

    (在Python中没有do…while循环,)循环语句当条件为正确时,允许我们执行一个语句或语句组多次执行。

  2. while 语句

    1. 作用:

      在给定的判断条件为 true 时执行循环体,否则退出循环体,

    2. 语法:

      while 真值表达式:

      ​ 足条件执行的循环体

      else:

      ​ 条件不满足执行的语句

    3. 说明:

      1. 先判断条件,如果满足则执行循环体,如果不满足则执行一次else子句。
      2. else 最多只有1个。
      3. 死循环,循环条件永远成立。比如忘记编写循环条件
  3. for 语句

  4. 作用:用来遍历可迭代对象的元素。

    1. 可迭代对象:能够依次获取数据元素的对象。例如:字符串 ”abcded”
  5. 语法:

for 变量列表 in 可迭代对象:

​ 循环体

else:

​ 循环过后执行的语句

  1. 说明:

    1. else子句可以省略
    2. 循环体中有break语句,退出时else不执行。

跳转函数 break/continue

  1. 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
    
  2. continue 语句

    跳过本次循环,继续下次循环。仅仅判断本次循环中:剩余语句是否执行。然后继续进行下一轮循环,所以continue禁止直接写在循环语句中,一般单独放在判断语句中。

    start=101
    
    end=183
    
    i=100
    
    while i<=1820:
      i=i+1#如果这句话放在continue后则不能进行全部的循环
      if i%17!=0:
        continue#不能被17整除的数字过滤掉,不执行下面的print,直接进入下此
        print(i)
    
  3. pass

    它只在语法上需要一条语句但程序不需要执行任何操作.例如:

    while True:
    … pass

迭代器与生成器

迭代器Iterator

  1. 迭代-Iteration

    迭代是Python最强大的功能之一,是访问集合元素的一种方式:集合的第一个元素开始访问,直到所有的元素被访问完结束。

  2. range函数

    1. 作用:可以生成一系列整数的可迭代对象。

    2. 语法:range(开始点,结束点,间隔) 说明:

      1. 返回的数字不包含结束点。
      2. 间隔默认值为1
      3. 默认开始点为0
    3. 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) # 空 
      
  3. 迭代器

    迭代器是一个可以记住遍历的位置的对象。字符串,列表或元组对象都可用于创建迭代器。两个基本的方法:iter()next()。迭代器对象可以使用常规for语句进行遍历。

    1. 可迭代对象:Iterable:

      1. 凡是可作用于for循环的对象都是Iterable 迭代对象类型;

        Python的for循环本质上就是通过不断调用next()函数实现的

        1. 用isinstance()判断一个对象是否是Iterable对象:
      2. 类别

        1. 集合数据类型,如list、tuple、dict、set、str等;

        2. generator,包括生成器和带yield的generator function。

    2. 迭代器:Iterator

      1. 凡是可作用于next(),__next__函数的对象都是Iterator 迭代器 类型,它们表示一个惰性计算的序列;

      2. list、dict、str等数据类型不是Iterator?Iterator对象表示的是一个数据流,Iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误。Iterator甚至可以表示一个无限大的数据流,例如全体自然数,计算是惰性的,只有在需要返回下一个数据时它才会计算 。而使用list是永远不可能存储全体自然数的,长度是一定的。

    3. 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
    
    
    

生成器 generator

  1. 定义:

    使用了 yield 的函数被称为生成器(generator)一边循环一边计算的机制。生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。

    不使用return 返回值,而是生成多个值,每次返回一个。在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回yield的值。并在下一次执行 next()方法时从当前位置继续运行。实例使用 yield 实现斐波那契数列.

  2. 作用

    1. 在循环的过程中不断推算出后续的元素,这样就不必创建完整的list,从而节省大量的空间。

      通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。

  3. 创建

    1. 把一个列表生成式的[]改成()

      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
      <generator object <genexpr> at 0x7f96d0cdcc10>
      0
      1
      '''
      
      
    2. 函数定义中包含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
      '''
      
      

函数与模块

函数定义与实现

1. 函数的介绍

函数(Function)是封装好的代码块, 用于封装一个特定的功能,表示一个行为实现单一或相 关联功能的代码段

  1. 类别

    Python中预制了很多内置函数

    开发者也可以创建自定义函数

  2. 特点

    隐藏具细节的代码

    提高代码的利用率

    提高可读性,便于调试

  3. 定义语法:

    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
    
    
    
    

    说明:

    1. def关键字,全称define,意为”定义”。

    2. 函数名:建议使用动词,对函数体中语句的描述。

    3. 形参列表:形式参数 。方法定义者要求调用者提供的信息

    4. 函数体:完成该功能的语句。建议语句不要太多

    5. 返回值:方法定义者告诉调用的结果。语法:return 结果。说明:

      1. 不写return关键字,相当于返回None

      2. return 还意味着方法结束

      3. 虽然每个函数对应一个返回值,但这个返回值可以是字典/或类似字典的结构

    6. 补充

      1. 函数的第一行语句可以选择性的使用文档字符串存储函数与参数的说明。

2.变量作用域

  1. 局部/全局:

    定义在函数内部的变量拥有一个局部作用域,定义在函数外的拥有全局作用域。

    查找规则:LEGB

  2. 类型:

    1. Local 局部作用域:函数内部。在方法体内部定义的变量,调用函数时才被创建,函数结束后自动销毁。
    2. Encolsing 外部嵌套作用域:函数嵌套
    3. global 全局作用域:
      1. 利用global 在一个函数内部修改全部变量
      2. py文件内部 定义在.py文件中的变量。函数体内部可以访问,但是不能直接修改(先使用global语句声明才能修改)
    4. Builtins内建模块作用域:builtins.p

3.参数

  1. 定义:

    参数就是函数的输入数据,在程序运行时根据参数不同执行不同代码。。

  2. 形参是parameter,实参是argument。

    1. 形参”全称为"形式参数" 本质是一个名字,不占用内存空间

      由于它不是实际存在变量,所以又称虚拟变量。用于定义函数名和函数体的时候使用的参数,目的是用来接收调用该函数时传入的参数。只有在程序执行过程中调用了函数,形参才有可能得到具体的值,并参与运算求得函数值。

    2. 实参的本质是一个变量,已经占用内存空间。

      实参” 实际参数。在调用有参函数时,函数名后面括号中的参数实参可以是常量、变量或表达式。在调用函数时,实参将赋值给形参。因而,必须注意实参的个数,类型应与形参一一对应,并且必须要有确定的值。

    3. 案例

      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)#实参
      
      
  3. 实参传递方式

    1. 位置传参实参与形参的位置依次对应。

    2. 序列传参实参用*将序列拆解后与形参的位置依次对应

    3. 关键字传参 实参根据形参的名字进行对应。

    4. 字典传参 :实参用**将字典拆解与形参的名字进行对应。

      参数传递的*args和**kwargs。允许定义的函数接受任意数目的参数

      主要是用于将不定数的参数传递给一个函数:预先并不知道函数使用者会传递多少个参数给。

      *args:是用来发送一个非键值对的可变数量的参数列表给一个函数:

      **kwargs:允许你将不定长度的键值对作为参数传递给一个函数。如果你想要在一个函数里处
      理带名字的参数你应该使用* kwargs。r

  4. 传递规则和语法

    位置形参 --> 星号元组形参 --> 命名关键字形参 --> 双星号字典形参

    def fun1(a,b,*args,c,d,**kwargs):
    
    print(a,b, args,c,d, kwargs)
    
    1. 默认(缺省)参数

      def 函数名(参数1 = 默认值1):
        函数体
       
      

      说明:

      1. 缺省参数必须自右至左依次存在,如果一个参数有默认值,则右侧所有参数必须都有默认值。
      2. 缺省参数可以有0个或多个
    2. 位置形参

      def 函数名(参数1):
      函数体
      
    3. 星号元组形参

      def 函数名(*args):
      
      函数体
      
      1. 作用:收集多余的位置形参
      2. 说明:
        1. 一般命名为 *args
        2. 形参列表最多只能有一个
    4. 命名关键字形参

      def 函数名(*,参数名):
      
      函数体
      
      def 函数名(*args,参数名):
      
      函数体
      

      作用:强制实参使用关键字传递

    5. 双星号字典形参

      def 函数名(**kwargs):
      
      函数体
      
      1. 作用:收集多余的关键字传参
      2. 说明:
        1. 一般命名kwargs
        2. 形参列表中最多只能有一个
  5. 可变/不可变类型在传参时的区别:

    1. 不可变类型的数据传参时,函数内部不会改变原数据的值。

      不可变类型:字符串、元组、固定集合、整数、浮点数、复数。

    2. 可变类型的数据传参时,函数内部可能改变原数据的值。

      可变类型列表、字典、集合

  6. 参数使用技巧

    # 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. 变参数列表
    
    ”“”
    让函数调用可变个数的参数.这些参数被包装进一个元组(查看元组和序列).在这些可变个数的参数之前,可以有零到多个普通的参数
    “”“
    
    

模块与包

模块module

  1. 定义:

    模块是包含函数和变量的文件,其后缀名是.py。模块可以被别的程序引入,以使用该模块中的函数等功能。这也是使用python标准库的方法。

  2. 作用:

    1. 可维护性更强

      各个功能分别作为一个模块,分别维护修改。

      可以定义多个函数和变量。

    2. 方便代码重用

      各个模块可以反复被各个程序调用,同时避免函数名和变量名冲突

  3. 导入及定位

    1. 导入

      import 语句。当解释器遇到 import 语句,如果模块在当前的搜索路径就会被导入。一个模块只会被导入一次 不管你执行了多少次import这样可以防止导入模块被一遍又一遍地执行。

    2. 定位

      1. Python的搜索路径:

        当前包 —>内置函数—>sys.path(环境变量).首先会在当前的目录进行查找,然后在内置函数中查找,最后在环境变量中查找

      2. 搜索路径

        搜索路径是由一系列目录名组成的,搜索路径被存储在sys模块中的path变量,Python解释器就依次从这些目录中去寻找所引入的模块。这看起来很像环境变量,事实上,也可以通过定义环境变量的方式来确定搜索路径。搜索路径是在Python编译或安装的时候确定的,安装新的库应该也会修改

      3. sys.path

        1. 查看

          sys.path输出是一个列表,

          其中第一项是空串’’,代表当前目录(若是从一个脚本中打印出来的话,可以更清楚地看出是哪个目录),亦即我们执行python解释器的目录(对于脚本的话就是运行的脚本所在的目录)

        2. 修改

          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']
          
          
          
  4. 模块属性

    1. dir——列出对象的所有属性及方法

      内置的函数 dir() 可以找到模块内定义的所有名称。以一个字符串列表的形式返回,如果没有给定参数,那么 dir() 函数会罗列出当前定义的所有名称,给定参数,这些参数可以进一步dir:

      1. 底下是双下划线的属性是系统内置的属性,

        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'
        
    2. help——查看类,方法的帮助信息

      如果没有给定参数,那么 help() 函数会罗列出当前定义的所有名称,给定参数,这些参数可以进一步help(hello.add)。

      • 帮助文档:[mac](file:///Library/Frameworks/Python.framework/Versions/3.7/Resources/English.lproj/Documentation/library/index.html )

      • 这是编写模块的关键,用于帮助文档的调用者,所以写注释要完善而规范,细节规范在pycharm中会有相对应的建议。比如:编码前对模块的功能描述、编写中写好每一步的规范:参数、返回值

  5. python标准库中模块

    1. 标准模块:The Python Standard Library

      Python 本身带着一些标准的模块库,在 Python 库参考文档中将会介绍到(就是后面的"库参考文档")。有些模块直接被构建在解析器里,这些虽然不是一些语言内置的功能,但是他却能很高效的使用,甚至是系统级调用也没问题。这些组件会根据不同的操作系统进行不同形式的配置,比如 winreg 这个模块就只会提供给 Windows 系统。

包 package

  1. 包的简介

    包是一种管理 Python 模块命名空间的形式,采用"点模块名称"。比如一个模块的名称是 A.B, 那么他表示一个包 A中的子模块 B 。不同的作者都可以提供 NumPy 模块,或者是 Python 图形库。采用点模块名称这种形式也不用担心不同库之间的模块重名的情况。

  2. 作用

    可以用来组织模块(可以包含其它模块的模块)

    模块重名问题解决

  3. 建立

    目录必须包含文件_init_.py.这也是包 package 和模块的区别

  4. 引入整个包:

    1. 包的引用 import module

      1. 路径

        在导入一个包的时候,Python 会根据 sys.path 中的目录来寻找这个包中包含的子目录。

      2. _init_.py\ __

        目录只有包含一个叫做 init.py 的文件才会被认作是一个包,主要是为了避免一些滥俗的名字(比如叫做 string)不小心的影响搜索路径中的有效模块。 (init.py相当于把自身整个文件夹当作一个包来管理,每当有外部import的时候,就会自动执行里面的函数)。

      3. 用户可以每次只导入一个包里面的特定模块,必须使用全名去访问,比如:

      import xiaowu.pay #将会导入子模块:xiaowu.pay
      
      help(pay) #访问会出错
      
      help(xiaowu.pay)#必须使用全名去访问:
      
    2. from package import item只引入所需要的属性和方法

      这种形式的时候,对应的item既可以是包里面的子模块(子包),或者包里面定义的其他名称,比如函数,类或者变量。

      import语法会首先把item当作一个包定义的名称,如果没找到,再试图按照一个模块去导入。如果还没找到,恭喜,一个:exc:ImportError 异常被抛出了。反之,如果使用形如import item.subitem.subsubitem这种导入形式,除了最后一项,都必须是包,而最后一项则可以是模块或者是包,但是不可以是类,函数或者变量的名字。

      1. 从当前目录引入

        from . import xx

      2. from module.xx.xx import xx

      3. 指定别名:from module.xx.xx import xx as rename

      4. 引入所有: from module.xx.xx import *

封装自己的模块和包

添加模块搜索路径

    1. 设置Python模块的搜索路径有几种方式?

      1. 设置PYTHONPATH环境变量

        1. mac 通过 终端 添加PYTHONPATH:

          1. 永久设置模块的搜索路径

            1. 进入终端,配置环境变量
            2. open ~/.bash_profile
            3. 在文件末尾添加:
              1. export PYTHONPATH =“对应的路径”
            4. 保存退出 ,运行程序
          2. 临时设置

            1. 进入终端,找到对应文件

            2. 添加临时路径:

              export PYTHONPATH =“对应的路径”

            3. 运行程序 程序

      2. 通过添加.pth文件

        在site-packages添加一个路径文件,如mypkpath.pth,必须以.pth为后缀,写上你要加入的模块文件所在的目录名称就是了

        • 需要在Python的相关目录中放置一个名称是ze,扩展名是.pth

        • 这个文件的每一行就是一个路径。

        • 当Python运行程序时。当Python运行脚本时,它就会自动的搜索这个文件。如果找到,就会将对应的路径添加到途径的添加到系统路径中。

        • 在哪一个文件中放置这个.pth文件?

          • 在Python或者anoconda的对应文件中。
        • 在Python中。

          • 通过控制台进入Python的根目录。lib
          • 建立对应的文件,写入地址
      3. 通过设置sys.path

        • 暂时设置模块的搜索路径
        1. import sys

        2. 查看sys.path

        3. 添加sys.path.append(“c:\”)

      4. 通过PyCharm,可以直接设置

        模块文件》make directory as 》source root

    2. 永久设置Python模块搜索路径。

      1. PYTHONPATH
      2. .PTH
      3. PyCharm
    3. 临时设置Python模块的搜索路径。

      1. Sys.path
      2. 临时设置PYTHONPATH

标准模块

  1. 标准库

    标准库的意思表示这是一个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 模块。

contextvars 上下文变量

上下文变量

手动上下文管理

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

Tk图形用户界面(GUI)

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

Python运行时服务

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 —— 指定域的配置钩子

自定义 Python 解释器

code — 解释器基类

codeop — 编译Python代码

导入模块

zipimport — 从 Zip 存档中导入模块

pkgutil — 包扩展工具

modulefinder — 查找脚本使用的模块

runpy — Locating and executing Python modules

importlib — import 的实现

Using importlib.metadata

Python 语言服务

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

Unix 专有服务

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 包索引 即可获取这些第三方模块

科学计算Sklearn, Numpy, Pandas

人工智能:Tensorflow, PyTorch

网络爬虫:Scrapy, Request, BeautifulSoap

可视化:matplotlib

文档处理:jieba,NTLK

文件读写

  1. open() 方法

    open() 方法用于打开一个文件,并返回文件对象,在对文件进行处理过程都需要使用到这个函数,如果该文件无法被打开,会抛出 OSError。

    **注意:**使用 open() 方法一定要保证关闭文件对象,即调用 close() 方法。

  2. 语法

    open(file, mode=‘r’) 文件名(file)和模式(mode)。

    • file:必需,文件路径(相对或者绝对路径)。
      mode:
      buffering:设置缓冲
      encoding:一般使用utf8
      errors:报错级别
      newline:区分换行符
      closefd:传入的file参数类型
      opener:
  3. file 必须,文件路径(相对或者绝对路径)。

    1. [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 或者 反斜杆

      两个斜杠:\(第一个\是转义符)\winpath2 = ‘C:\Users\Hjx\Desktop\text.txt’
      单个反斜杠/通用 :win liuxpath1 = ‘C:/Users/Hjx/Desktop/text.txt’
      r 用于防止字符转义path3 = r’C:\Users\Hjx\Desktop\text.txt’
  4. mode 可选,文件打开模式

    1. 判断逻辑

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bcTjVpET-1614984312171)(/Users/wu/Documents/image-20210126141753228.png)]

    2. 基础模式

      模式rr+ww+aa+
      ++++
      +++++
      创建++++
      覆盖++
      指针在开始++++
      指针在结尾++
    3. 全部模式

      模式描述
      t文本模式 (默认)。
      x写模式,新建一个文件,如果该文件已存在则会报错。
      b二进制模式。与其他模式结合使用,不能单独
      +打开一个文件进行更新(可读可写)。与其他模式结合使用,不能单独
      U通用换行模式(不推荐)。
      r以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。
      rb以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。一般用于非文本文件如图片等。
      r+打开一个文件用于读写。文件指针将会放在文件的开头。
      rb+以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。一般用于非文本文件如图片等。
      w打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。
      wb以二进制格式打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。一般用于非文本文件如图片等。
      w+打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被覆盖。如果该文件不存在,创建新文件。
      wb+以二进制格式打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。一般用于非文本文件如图片等。
      a打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
      ab以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
      a+打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。
      ab+以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。
  5. 函数

    序号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/81176687with 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

  1. 定义

    在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator),扩展原函数的功能。decorator就是接受一个函数作为参数,并返回一个函数。

    一句话解释什么样的语言能够用装饰器? 函数可以作为参数传递的语言,可以使用装饰器

  2. 语法

    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()#结果同时执行
    
    1. 借助Python的@语法,把decorator置于函数的定义处

    2. 装饰器和被装饰函数的顺序

      当装饰器和被装饰函数定义在同一个.py文件时,装饰器需要定义在被装饰函数的前面,python代码是自上而下执行,从而使得程序在执行时可以先调用上面的装饰器

    3. 运行顺序如上图

      1. 装饰器中 临时保存 传入函数的返回值 ,注意位置

      2. 完整的decorator,调用 functools.wraps ,避免了装饰器干扰内置函数

        1. 问题:

          测试代码中调用 print(‘doc: {0}’.format(hello._doc_)) 、 print(‘name: {0}’.format(hello.__name__)),返回的是装饰器的内置函数.返回的那个wrapper2()函数名字就是’wrapper’,所以,需要把原始函数的name等属性复制到wrapper()函数中,否则,有些依赖函数签名的代码执行就会出错

        2. 剖析:

          函数也是对象,它有__name__等属性,经过decorator装饰之后的函数,它们的__name__已经从原来的’now’变成了’wrapper’:

        3. 解决:

          不需要编写wrapper.name = func.__name__这样的代码,Python内置的functools.wraps就是干这个事的,所以,一个完整的decorator的写法如下:

      3. 定义多个装饰器,注意执行的顺序。避免传递函数的嵌套造成问题

深拷贝和浅拷贝

Python 引用

对象的引用就是赋值的过程。

我们举个栗子:

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)]

深拷贝与浅拷贝

数字和字符串中的内存都指向同一个地址,所以深拷贝和浅拷贝对于他们而言都是无意义的。也就是说,我们研究深拷贝和浅拷贝,都是针对可变对象进行研究,最常见的情况就是列表

  1. 深拷贝

    所谓的深拷贝,也就是基于被拷贝的可变对象,建立一个完全一样的拷贝后的对象,二者之间除了长得一模一样,但是相互独立,并不会互相影响。经过深拷贝操作后,拷贝后得到的对象的任何操作均无法改变原始对象。Python的原生拷贝操作需要导入copy包,其中的deepcopy()函数表示深拷贝

  2. 浅拷贝

    其实既然 Python 的 copy 有深浅之分,那显然浅拷贝必然有不一样的地方。

    1. 如果只是针对由不可变的对象组成的单层常规列表,浅拷贝和深拷贝并无任何区别。

      1. 切片与浅拷贝
        结论:切片其实就是对源列表进行部分元素的浅拷贝!
      单层浅拷贝
    2. 嵌套列表

      1. 不可变对象组成的列表,浅拷贝和深拷贝效果一样,拷贝前后互相独立,互不影响;

      2. 可变元素时,浅拷贝只是建立了一个由该元素指向新列表的引用(指针),当该元素发生变化的时候,拷贝后的对象也会发生变化;

      3. 深拷贝完全不考虑节约内存,浅拷贝则相对来讲比较节约内存,浅拷贝仅仅是拷贝第一层元素;

        image-20210127164620569
# 深拷贝
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]]
# 比较发现,切片结果的变化值,没有传递给了源列表。说明对于不可变元素,切片前后互相独立。

## 综合比较,可以发现,切片的效果其实就是浅拷贝!

面向对象

介绍

1. 简介

面向过程面向对象
定义分析出解决问题的步骤,然后逐步实现。找出解决问题的人,然后分配职责。
理解例如:婚礼筹办 – 发请柬(选照片、措词、制作) – 宴席(场地、找厨师、准备桌椅餐具、计划菜品、购买食材) – 婚礼仪式(定婚礼仪式流程、请主持人)例如:婚礼筹办 – 发请柬:找摄影公司(拍照片、制作请柬) – 宴席:找酒店(告诉对方标准、数量、挑选菜品) – 婚礼仪式:找婚庆公司(对方提供司仪、制定流程、提供设备、帮助执行)
公式程序 = 算法 + 数据结构程序 = 对象 + 交互
优点所有环节、细节自己掌控。思维:更接近于人的思维方式。 有利于梳理归纳、分析解决问题。
技术上:高复用:对重复的代码进行封装,提高开发效率。高扩展:增加新的功能,不修改以前的代码。高维护:代码可读性好,逻辑清晰,结构规整
缺点考虑所有细节,工作量大。– 高扩展:增加新的功能,不修改以前的代码。

2.三大特征

封装、继承、多态

3.类(Class) &对象

一个抽象的概念,即生活中的”类别”。拥有实例、属性和方法。用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。

  1. 概念

    1. **类变量:**类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。
    2. 实例化:创建一个类的实例,类的具体对象
    3. 数据成员:名词类型的状态。类变量或者实例变量用于处理类及其实例对象的相关的数据。
    4. **实例变量:**在类的声明中,属性是用变量来表示的。这种变量就称为实例变量,是在类声明的内部但是在类的其他成员方法之外声明的。
    5. **局部变量:**定义在方法中的变量,只作用于当前实例的类。
    6. 方法成员:动词类型的行为。
    7. 方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。
  2. 类与类行为不同,对象与对象数据不同。例如:

    1. 学生student是一个类,具有姓名,年龄等数据; 具有学习study,工作work等行为。

      对象:悟空同学,28岁

      八戒同学,29岁。

    2. 车 car是一个类,具有类型type,速度speed等数据;启动start,停止stop,行驶run等行为。

      对象:宝马,180.

      比亚迪,100.

    3. 狗dog是一个类,具有类型,姓名,重量weight等数据,拉臭臭shit,玩play等行为。

      对象:拉布拉多,米咻。 金毛,

  3. 设计原则

    1. 开-闭原则(目标、总的指导思想)

      Open Closed Principle

      对扩展开放,对修改关闭。

      增加新功能,不改变原有代码。

    2. 类的单一职责(一个类的定义)

      Single Responsibility Principle

      一个类有且只有一个改变它的原因。

    3. 依赖倒置(依赖抽象)

      Dependency Inversion Principle

      客户端代码(调用的类)尽量依赖(使用)抽象的组件。

      抽象的是稳定的。实现是多变的。

    4. 组合复用原则(复用的最佳实践)

      Composite Reuse Principle

      如果仅仅为了代码复用优先选择组合复用,而非继承复用。

      组合的耦合性相对继承低。

    5. 里氏替换(继承后的重写,指导继承的设计)

      Liskov Substitution Principle

      父类出现的地方可以被子类替换,在替换后依然保持原功能。

      子类要拥有父类的所有功能。

      子类在重写父类方法时,尽量选择扩展重写,防止改变了功能。

    6. 迪米特法则(类与类交互的原则)

      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类,这是所有类最终都会继承的类。

  1. 类名所有单词首字母大写.

  2. 初始化 :很多类都倾向于将对象创建为有初始状态的。

    定义一个名为 _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 <module>
    print (counter.__secretCount)  # 报错,实例不能访问私有变量
AttributeError: 'JustCounter' object has no attribute '__secretCount
‘’‘
  1. 说明

    1. 不建议通过类名访问实例方法

    2. 至少有一个形参,第一个参数绑定调用这个方法的对象,一般命名为"self"。

      self 变量绑定的是被创建的对象,名称可以随意

    3. 创建多少对象,方法只有一份,并且被所有对象共享。

类对象 object

1. 定义

  1. 对象:

    通过类定义的数据结构 进行实例,是一个相对概念,即归属于某个类别的”个体”。子定义函数时,self代表的就是对象。对象包括两个数据成员(类变量和实例变量)和方法。。

  2. 属性 :对象具有的静态特征

  3. 方法:对象具有的动态特征。类中定义的函数

  4. 类对象支持两种操作:属性引用和实例化。

    1. 实例化

      变量 = 构造函数 (参数列表)

    2. 属性引用:

      使用和 Python 中所有的属性引用一样的标准语法:obj.name。类对象创建后,类命名空间中所有的命名都是有效属性名。

  5. 案例:

    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.定义

隐藏对象的信息,留出访问接口。隐藏实现的细节,将类的某些信息隐藏在类的内部,不允许外部程序访问。通过该类的提供的方法来实现对隐藏信息的操作和访问。通过规定的方法访问数据,向类外提供功能。数据角度讲,将一些基本数据类型复合成一个自定义类型。

2. 设计角度讲

  1. 分而治之

    将一个大的需求分解为许多类,每个类处理一个独立的功能。

    拆分好处:便于分工,便于复用,可扩展性强。

  2. 封装变化

    变化的地方独立封装,避免影响其他类。

  3. 高内 聚

    类中各个方法都在完成一项任务(单一职责的类)

  4. 低 耦 合

    类与类的关联性与依赖度要低(每个类独立),让一个类的改变,尽少影响其他类。

    最高的内聚莫过于类中仅包含1个方法,将会导致高内聚高耦合。

    最低的耦合莫过于类中包含所有方法,将会导致低耦合低内聚。

3. 作用

    1. 简化编程,使用者不必了解具体的实现细节,只需要调用对外提供的功能。
    2. 松散耦合,降低了程序各部分之间的依赖性。
    3. 数据和操作相关联,方法操作的是自己的数据。

4.私有属性

  1. 作用

    无需向类外提供的成员,可以通过私有化进行屏蔽。

  2. 做法

    两个下划线开头,声明该属性为私有,不能在类地外部被使用或直接访问。在类内部的方法中使用时self.__private_attrs。可以通过内部的函数操作。

  3. 本质

    障眼法,实际也可以访问。

    私有成员的名称被修改为:_类名__成员名,可以通过_dict_属性或dir函数查看。

  4. 类的内置方法

    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)
    '''
    
    1. _init_ 初始化变量: 构造函数,创建对象后,就立刻被默认调用了,可接收参数

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WLql1FJf-1614984312173)(/Users/wu/Documents/image-20210131224621006.png)]

    2. _str_:返回值为一个字符串对象

      和内置函数str实际上实现的是同一功能,

      1. 使用

        由于object类定义了__str__方法,因此所有类都会继承该方法,除非有自定义类重写了该方法。什么情况下会触发__str__方法呢?主要有如下情况会触发__str__的调用:

        1. 在交互环境下直接输入str(对象名)查看对象内容;

        2. print(对象)查看对象内容时

        3. 直接调用“对象.str()”方法;

        4. 由于列表以及字典等容器总是会使用 repr 方法,即使调用__str__方法访问输出的还是__repr__访问内容。

          # __str__
          #打印时触发
          class A:
            def __str__(self):
              #打印时执行这行代码
              return ’ok‘
            print(A()) #相当于print(A().__str__())
          
          
    3. _slots_

      1. 作用:限制类的属性.限定一个类创建的实例只能有固定的实例变量,不能再额外添加。、

      2. 语法:在类中定义 _slots_ = (“变量名1”,”变量名2”……)

      3. 说明: 含有__slots__属性的类所创建的对象没有__dict__属性, 即此实例不用字典来存储对象的实例属性。

      4. 优点:访止用户因错写属性的名称而发生程序错误。

      5. 缺点:丧失了动态语言可以在运行时为对象添加变量的灵活性。

    4. __new__

      1. new至少要有一个参数cls,代表当前类,此参数在实例化时由 Python解释器自动识别

      2. new必须要有返回值,返回实例化出来的实例,这点在自己实现new时要特别注意,可以 return父类(通过 super(当前类名,cs))neW出来的实例,或者直接是 object的neW出来的实例

      3. init有一个参数sef,就是这个new返回的实例,init在neW的基础上可以完成一些其它初始化的动作,init不需要返回值

      4. 如果new创建的是当前类的实例,会自动调用init函数,通过 return语句里面调用的new函数的第一个参数是cls来保证是当前类实例,如果是其他类的类名,那么实际创建返回的就是其他类的实例,其实就不会调用当前类的init函数,也不会调用其他类的init函数

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EoK0IkAO-1614984312174)(/Users/wu/Documents/image-20210131225637306.png)]

    5. _del_ : 析构函数,释放对象时使用_

    6. _repr : 打印,转换_

    7. _next_ 迭代函数规则

    8. ​ _iter_ 生成迭代器

    9. _len_: 获得长度_

    10. _cmp: 比较运算__

    11. _call_: 函数调用_

    12. _add_: 加运算_

    13. ……

  5. 静态方法 /属性@property

    1. 定义常用的工具函数。

      公开的实例变量,缺少逻辑验证。私有的实例变量与两个公开的方法相结合,又使调用者的操作略显复杂。而属性可以将两个方法的使用方式像操作变量一样方便

    2. 定义:

      @staticmethod
      def 方法名称(参数列表):
      
      #				方法体
      
      #		案例:
        @property
        def name(self):
          return self.__name
      
        @name.setter
        def name(self, name):
          self.__name = name
      
      

      (使用@ staticmethod修饰的目的是该方法不需要隐式传参数。静态方法不能访问实例成员和类成员)

    3. 调用:

      对象.属性名 = 数据

      变量 = 对象.属性名

      不建议通过对象访问静态方法

    4. 说明:

    – 通常两个公开的属性,保护一个私有的变量。

    – @property 负责读取,@属性名.setter 负责写入

    – 只写:属性名= property(None, 写入方法名)

继承

1. 定义:

类与类之间的关系,抽取类与类之间的公共属性,建立夫类。重复利用父类,建立子类。重用现有类的功能与概念,并在此基础上进行建立新类。事物具有一定的层次、渊源,继承可以统一概念。

  1. 相关概念

    父类(基类、超类)、子类(派生类)。

    父类相对于子类更抽象,范围更宽泛;子类相对于父类更具体,范围更狭小。

    单继承:父类只有一个(

    多继承:父类有多个

    Object类:任何类都直接或间接继承自 object 类

  2. 作用

    隔离客户端代码与功能的实现方式。

    适用于:多个类在概念上是一致的,且需要进行统一的处理

  3. 优点

    一种代码复用的方式。

    以层次化的方式管理类。

  4. 缺点

    耦合度高

2.语法

# 单继承
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() 

’‘’
执行以上程序输出结果为:
	我
’‘’

  1. BaseClassName(示例中的基类名)

    必须与派生类定义在一个作用域内。除了类,还可以用表达式,基类定义在另一个模块中时这一点非常有用:class DerivedClassName(modname.BaseClassNam

  2. 同名方法的解析顺序(MRO, Method Resolution Order):

    类自身 --> 父类继承列表(由左至右)–> 再上层父类

    括号中基类的顺序,若是基类中有相同的方法名,而在子类使用时未指定,python从左至右搜索 即方法在子类中未找到时,从左到右查找基类中是否包含方法。

  3. 子类(派生类)必须拥有父类(基类)全部属性,可以新增。

    即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。

  4. 继承的连续

    子类的子类,依然是子类

  5. 方法重写

    如果你的父类方法的功能不能满足你的需求,你可以在子类重写你父类的方法,

  6. ?内置函数

    isinstance(obj, class_or_tuple)

    返回这个对象obj 是否是某个类的对象,或者某些类中的一个类的对象。

3.继承方式

  1. 单继承

    只有一个父类

  2. 多继承

    一个子类继承两个或两个以上的基类,父类中的属性和方法同时被子类继承下来。

多态

1. 定义

​ 父类的同一种动作或者行为,在不同的子类上有不同的实现。

​ 子类对同一信息,有不同的响应

​ 必须满足继承关系,并且对子类有方法的重写。

  1. 作用

    继承将相关概念的共性进行抽象,多态在共性的基础上,体现类型的个性化(一个行为有不同的实现)。增强程序扩展性,体现开闭原则。

  2. 重写

    子类实现了父类中相同的方法(方法名、参数),在调用该方法时,实际调用的是子类的方法。

    1. 内置可重写函数
    2. 运算符重载

os.path — 常用路径操作

递归文件夹创建函数。像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')

sys — 系统相关的参数和函数

  1. import sys

  2. sys.path

    查看Python的搜索路径,输出是一个列表,其中第一项是空串’’,代表当前目录(若是从一个脚本中打印出来的话,可以更清楚地看出是哪个目录),亦即我们执行python解释器的目录(对于脚本的话就是运行的脚本所在的目录)

  3. 添加sys.path.append(“c:\”)

    将自定义模块的路径添加到系统的环境变量(sys.path)

re — 正则表达式操作

re简介

  1. 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

  2. 正则表达式

    (regular expression)描述了一种字符串匹配的模式(pattern),是用于处理字符串,匹配字符串.

    模式描述在搜索文本时要匹配的一个或多个字符串。

    正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配.

  3. 设计思想

    用一种描述性的语言(特定的符号)来给字符串定义一个规则,凡是符合规则的字符串,我们就认为它“匹配”了,否则,该字符串就是不合法的。

    构造正则表达式的方法和创建数学表达式的方法一样。用多种元字符与运算符可以将小的表达式结合在一起来创建更大的表达式。

    组件:单个的字符、字符集合、字符范围、字符间的选择或者所有这些组件的任意组合。

    普通字符、非打印字符

  4. 为什么使用正则表达式?

    典型的搜索和替换操作对于对静态文本执行可能已经足够了,但若采用这种方法搜索动态文本,即使不是不可能,至少也会变得很困难。通过使用正则表达式,可以:

    • 测试字符串内的模式。

      例如,可以测试输入字符串,以查看字符串内是否出现电话号码模式或信用卡号码模式。这称为数据验证。

    • 替换文本。

      可以使用正则表达式来识别文档中的特定文本,完全删除该文本或者用其他文本替换它。

    • 基于模式匹配从字符串中提取子字符串。

      可以查找文档内或输入域内特定的文本

re组件

组件:单个的字符、字符集合、字符范围、字符间的选择或者所有这些组件的任意组合。

普通字符、非打印字符

普通字符*

普通字符包括没有显式指定为元字符的所有可打印和不可打印字符。这包括所有大写和小写字母、所有数字、所有标点符号和一些其他符号。

非打印字符

非打印字符也可以是正则表达式的组成部分。下表列出了表示非打印字符的转义序列:

字符描述
\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
<number>引用编号为的分组匹配到的字符串
(?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"。
(?<!pattern)反向否定预查,与正向否定预查类似,只是方向相反。例如"(?<!95|98|NT|2000)Windows"能匹配"3.1Windows"中的"Windows",但不能匹配"2000Windows"中的"Windows"。
[\u4e00-\u9fa5]python正则匹配汉字的规则为

re模块常量

  • 常量即表示不可更改的变量,一般用于做标记。re模块中有9个常量,常量的值都是int类型!
    • 9个常量中,前5个(IGNORECASE、ASCII、DOTALL、MULTILINE、VERBOSE)有用处,两个(LOCALE、UNICODE)官方不建议使用、两个(TEMPLATE、DEBUG)试验性功能,不能依赖。
    • 常量可叠加使用,因为常量值都是2的幂次方值,所以是可以叠加使用的,叠加时请使用 | 符号,请勿使用+ 符号!
  1. IGNORECASE

    语法: re.IGNORECASE 或简写为 re.I

    作用: 进行忽略大小写匹配,在默认匹配模式下大写字母B无法匹配小写字母b,而在 忽略大小写 模式下是可以的。代码案例

  2. ASCII

    语法: re.ASCII 或简写为 re.A

    作用: 顾名思义,ASCII表示ASCII码的意思,让 \w, \W, \b, \B, \d, \D, \s 和 \S 只匹配ASCII,而不是Unicode。

    1. 在默认匹配模式下\w+匹配到了所有字符串,而在ASCII模式下,只匹配到了a、b、c(ASCII编码支持的字符)。注意:这只对字符串匹配模式有效,对字节匹配模式无效

    代码案例:

  3. DOTALL

    语法: re.DOTALL 或简写为 re.S

    作用: DOT表示.,ALL表示所有,连起来就是.匹配所有,包括换行符\n。

    1. 在默认匹配模式下.并没有匹配换行符\n,而是将字符串分开匹配;而在re.DOTALL模式下,换行符\n与字符串一起被匹配到。

    代码案例:

  4. MULTILINE

    语法: re.MULTILINE 或简写为 re.M

    作用:多行模式,当某字符串中有换行符\n,默认模式下是不支持换行符特性的,比如:行开头 和 行结尾,而多行模式下是支持匹配行开头的。

    1. 正则表达式中^表示匹配行的开头,默认模式下它只能匹配字符串的开头;而在多行模式下,它还可以匹配 换行符\n后面的字符。注意:正则语法中^匹配行开头、\A匹配字符串开头,单行模式下它两效果一致,多行模式下\A不能识别\n。

    代码案例

  5. VERBOSE

    **语法:**re.VERBOSE 或简写为 re.X

    **作用:**详细模式,可以在正则表达式中加注解!

    1. 默认模式下并不能识别正则表达式中的注释,而详细模式是可以识别的。当一个正则表达式十分复杂的时候,详细模式或许能为你提供另一种注释方式,但它不应该成为炫技的手段,建议谨慎考虑后使用!

    代码案例:

  6. OCALE

    语法: re.LOCALE 或简写为 re.L

    作用:** 由当前语言区域决定 \w, \W, \b, \B 和大小写敏感匹配,这个标记只能对byte样式有效。这个标记官方已经不推荐使用,因为语言区域机制很不可靠,它一次只能处理一个 “习惯”,而且只对8位字节有效。注意: 由于这个标记官方已经不推荐使用,而且我也没使用过,所以就不给出实际的案例!

  7. UNICODE

    语法: re.UNICODE 或简写为 re.U作用: 与 ASCII 模式类似,匹配unicode编码支持的字符,但是 Python 3 默认字符串已经是Unicode,所以有点冗余。

  8. ** DEBUG**

    语法: re.DEBUG

    作用: 显示编译时的debug信息。

    虽然debug模式下确实会打印编译信息,但我并不理解这是什么语言 以及表达的含义,希望了解的朋友能不吝赐教。

    代码案例:

  9. EMPLATE

    语法: re.TEMPLATE 或简写为 re.T作用: 我也没搞懂TEMPLATE的具体用处,

re模块函数

  • re模块有12个函数,我将以功能分类来讲解;这样更具有比较性,同时也方便记忆。
  1. 查找一个匹配项

查找 一个匹配项 返回的都是一个匹配对象(Match)

  1. search
    查找任意位置的匹配项。只要有符合正则表达式的字符串就匹配成功

  2. match
    必须从字符串开头匹配

  3. fullmatch
    整个字符串与正则完全匹配

  4. 查找多个匹配项

    两个方法基本类似,只不过一个是返回列表,一个是返回迭代器。我们知道列表是一次性生成在内存中,而迭代器是需要使用时一点一点生成出来的,内存使用更优。如果可能存在大量的匹配项的话,建议使用finditer函数,一般情况使用findall函数基本没啥影响

    1. findall
      从字符串任意位置查找,返回一个列表
    2. finditer
      从字符串任意位置查找,返回一个选代器
  5. 分割

    split 用正则表达式将某字符串分割成多段

    1. re.split(pattern, string, maxsplit=0, flags=0) 函数:用 pattern 分开 string , maxsplit表示最多进行分割次数, flags表示模式,就是常量!

    2. 与 str.split比较

      str.split函数功能简单,不支持正则分割,而re.split支持正则。二者的速度结论是:在 不需要正则支持 且 数据量和数次不多 的情况下使用str.split函数更合适,反之则使用re.split函数

      image-20210128100452145
  6. 替换

    1. sub

      1. 替换掉某字符串中被正则表达式匹配的字符,返回替换后的字符串

      2. re.sub**(pattern, repl, string, count=0, flags=0)**

        1. 函数参数讲解:

          repl替换掉string中被pattern匹配的字符

          repl替换内容既可以是字符串,也可以是一个函数哦! 如果repl为函数时,只能有一个入参:Match匹配对象。

          count表示最大替换次数

          flags表示正则表达式的常量。值得注意的是:sub函数中的入参:

    2. subn

      1. 替换掉某字符串中被正则表达式匹配的字符,返回替换后的字符串和替换次数
      2. re.subn**(pattern, repl, string, count=0, flags=0)** 函数与 re.sub函数 功能一致,只不过返回一个元组 (字符串, 替换次数)
  7. 编译正则对象

    compile函数template函数 将正则表达式的样式编译为一个 正则表达式对象 (正则对象Pattern),这个对象与re模块有同样的正则函数(后面我们会讲解Pattern正则对象)。

    1. compile
      正则表达式的样式编译为一个正则表达式对象(正则对象 Pattern),加快运行速度,并且重复利用
    2. template
      将正则表达式的样式编译为一个正则表达式对象,并添加re. TEMPLATE模式
  8. .其他

    1. escape
      可以转义正则表达式中具有特殊含义的字符,比如:,或者

    2. purge
      函数作用就是清除正则表达式缓存

其他

  1. 数量词的贪婪模式与非贪婪模式

    1. Python里数量词默认是贪婪的(在少数语言里也可能是默认非贪婪),总是尝试匹配尽可能长的字符;

    2. 非贪婪的则相反,总是尝试匹配尽可能少的字符。

      1. 表达式:表达式后加?(问号)
    3. 例如:

      ***** + 限定符都是贪婪的,因为它们会尽可能多的匹配文字,只有在它们的后面加上一个 ? **就可以实现非贪婪或最小匹配。*例如:

      正则表达式"ab*“如果用于查找"abbbc”,将找到"abbb"。而如果使用非贪婪的数量词"ab*?",将找到"a"。

  2. .r 的作用:反斜杠的困扰

与大多数编程语言相同,正则表达式里使用"“作为转义字符,这就可能造成反斜杠困扰。假如你需要匹配文本中的字符”\",那么使用编程语言表示的正则表达式里将需要4个反斜杠"\\\\前两个和后两个分别用于在编程语言里转义成反斜杠,转换成两个反斜杠后再在正则表达式里转义成一个反斜杠。

Python里的原生字符串可以使用r"\“表示。同样,匹配一个数字的”[\d](file:///d)“可以写成r”\d"。有了原生字符串,你再也不用担心是不是漏写了反斜杠,写出来的表达式也更直观。

  1. 匹配模式

    正则表达式提供了一些可用的匹配模式,比如忽略大小写、多行匹配等,这部分内容将在Pattern类的工厂方法re.compile(pattern[, flags])中一起介绍。

  2. 异常

    re模块还包含了一个正则表达式的编译错误,当我们给出的正则表达式是一个无效的表达式(就是表达式本身有问题)时,就会raise一个异常!

  3. 正则查找函数 返回匹配对象

    查找一个匹配项(search、match、fullmatch)的函数返回值都是一个 匹配对象Match ,需要通过match.group() 获取匹配值,这个很容易忘记。

datetime — 基本的日期和时间类型

  1. 函数介绍

    自定义日期和时间datetime.datetime()
    date
    time
    获取当前的时间和日期datetime.now()
    datetime.today()
    字符串转换datetime对象datetime.strptime()
    image-20210128110243613
    datetime****对象转换成字符串strftime
    加减操作,timedelta-时差timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0)
    得到的结果类型就是timedelta
  2. 代码演示

    # 与字符串 互相转化
    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)   <br />**参数** :  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 <b, 则 b >= 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)

Counter({‘l’: 9, ‘h’: 6, ‘f’: 5, ‘a’: 4, ‘;’: 4, ‘j’: 3, ‘d’: 3, ‘s’: 2, ‘:’: 2, ‘k’: 1, ‘g’: 1, ‘b’: 1})




# [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!')
   
   '''
   
   '''
  1. 三个关键知识点,即:

    1. 数据类型的创建
    2. 数据层的索引切片
    3. 数组运算
  2. 安装 Numpy

    Windows 系统: pip install numpy

    Mac 系统: pip3 install numpy

  3. 视图与副本

    创建视图,我们可以通过两种方法:Numpy 的切片操作以及调用view() 函数。

    浅拷贝在 Python 原生列表中,需要区分是否是嵌套列表。在 Numpy 中则简单一些,无论数组的维数是多少:在数组是1维的时候,规律和列表有些不一样,这里要特别注意

    1. 对视图或切片结果进行元素层面的修改时,操作的效果会反映到原始数组里。

    2. 视图的纬度更改并不会传递到原始数组 :改变视图的形状

      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])
      
      
  4. 副本

    副本也就是深拷贝,相对而言对内存的处理比较粗暴,也比较好理解。建立副本前后,两个变量是完全独立的。 Numpy建立副本的方法稍有不同。方法一,是利用Numy自带的copy函数;方法二,是利用deepcopy()函数

2. 基础类型——ndarray

  1. 介绍

    Numpy 最重要的一个特点就是它可以快速地创建一个 N 维数组对象(即 ndarray ,本文在 ndarray 对象和 数组 并不做概念上的区分),然后你可以利用 ndarray 这种数据结构非常高效地执行一些数学运算,并且语法风格和 Python 基本一致

    ndarray 是一个通用的同构数据多维容器,其中的所有的元素必须是相同的类型, Numpy 会根据输入的实际情况进行转换。「也就是如果创建的时候,没有指定数据类型,那 Numpy 就会以数组中最小的数据类型为数据。

    1. N 维数组对象

    2. 其他数据类型

    3. matrix 矩阵

  2. 创建

    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]]] ]
  3. 数组属性

    1. 数据类型 dtype

    2. 维度的数量 ndim

    3. 对象的尺度 shape

      对于矩阵,即 n 行 m 列,shape 是一个元组(tuple)

    4. 元素的数量 size

    相当于 shape 中 nXm 的值

    1. 各个元素内存 itemsize

      性返回数组中各个元素所占用的字节数大小

    2. 数组字节数 nbytes

      整个数组所需的字节数量,其值等于数组的 size 属性值乘以 itemsize 属性值

    3. 数组转置 T

    4. 复数实部 real

    5. 数组虚部 imag

    6. 即可迭代的对象 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) 
    

3. 常用函数

创建

  1. array

    1. 基于:list、tuple、Dataframe

    2. 一维数组用 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)
    
    

  2. arange

    1. 基于 固定步长

    2. 自动判断数据类型,

    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)
    
    
  3. linspace

    1. 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,则返回由数组和步长组成的元祖

    2. linspace(a, b , c, d) :在[a, b]中均匀的取c个数,d为False 不包含b, 默认为True

    3. 代码

      # 不设置 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)
      
  4. normal

    1. 指定分布(如标准正态分布)

    2. 20个指定分布(如标准正态分布)的数

    3. 代码

      tem = np.random.normal(0, 1, 20)	
      
  5. np.nan 空值

  6. np.frompyfunc 创建函数

    1. 将计算单元素的函数转换成,能对数组的每个元素进行操作的函数即可。

    2. 三个输入参数,分别是待转化的函数、函数的输入参数的个数、函数的返回值的个数

    3. 代码

      # 定义函数,购买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)
      
      
  7. np.zeros 全为0的数组

    np.zeros([4,5])
    np.ones([2,3])  
    eye = np.eye(7)
    np.diag([5,5,5,5,5])
    
  8. np.ones 生成元素全为1的数组:

  9. np.eye 单位矩阵形式的数组(n*n ,对角为1):

  10. np.diag 矩阵对角元素提取

等比数组

  1. geomspace() 指数等比数列

    1. geomspace(start, stop, num=50, endpoint=True, dtype=None)

      # start 和 stop,分别为区间的起始和终止值,为强制参数;

      # num 为待生成等比数列的长度,指定后,程序会自动计算取等比数列的公比;

      # endpoint默认为 True,结果为左闭右必区间。否则为 False,左闭右开区间;

    2. # 起始项为2,结束项为16,数列的长度为4。这里要注意,默认是左闭右闭的数组
      	In [51]: arr_geo0 = np.geomspace(2,16,4)
      	
      	In [52]: arr_geo0
      Out[52]: array([ 2., 4., 8., 16.]
      
  2. logspace 对数等比数列

    1. 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. # 起始项为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.])
      

随机数组

  1. random.rand ----[0, 1)之间的均匀分布的随机数组

    1. 生成 [0,1) 之间的数据,包含 0,不包含 1

    2. 函数的输入为若干个整数,表示输出随机数的大小为 d0×d1× …×dn

    3. 如果没有参数输入,则返回一个 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]])
      
  2. 生成 [0,1) 之间的浮点数

    numpy.random.random_sample(size=None)
    numpy.random.random(size=None)
    numpy.random.ranf(size=None)
    numpy.random.sample(size=None)

  3. random.uniform— [low, high) 之间的均匀分布

    1. # uniform 方法可以指定产生随机数的范围 [low, high),size 为数组的形状,输入格式为整形(一维)或者整形元祖

    2. # 如果不指定size的话,则返回一个服从该分布的随机数

      numpy.random.uniform(low=0.0, high=1.0, size=None)

    3. # 产生一个大小为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]])
      
      
  4. random.randn 服从标准正态分布的数组

    1. # 该方法和rand类似,函数的输入为若干个整数,表示输出随机数的大小为d0×d1× …×dn

    2. # 如果没有参数输入,则返回一个服从标准正态分布的float型随机数

      numpy.random.randn(d0, d1, …, dn)

  5. numpy.random.normal 服从 μ=loc,σ=scale 的正态分布的数组

  6. random.randint 指定区间 [low, high) 中离散均匀抽样的数组

  7. random.choice 从给定的一维数组中生成随机数

    概率抽样:
    对具体样本进行有放回或者无放回的抽样

  8. numpy.random.seed() 使得随机数据可预测

    设置相同的 seed,每次生成的随机数相同

    如果不设置 seed,则每次会生成不同的随机数

计算

当数组跟一个标量进行数学运算时,标量需要根据数组的形状进行扩展,然后执行运算。这个扩展的过程称为“广 播(broadcasting)”

  1. 直接加减乘除

    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]])

  2. 描述性统计

  3. np.mean() 均值

    1. 参数:axis=None, dtype=None,out=None,keepdims=np._NoValue
  4. np.median() 中位数

  5. percentile 分位数

    1. 最小值、25%分位数、中位数、75%分位数、最大值
    2. np.percentile(df, q=[0, 25, 50, 75, 100])
  6. np.var() 返回方差(variance)

  7. np.std() 回标准偏差(standard deviation)

  8. np.cov(arr1,arr2) 相关性矩阵

  9. np.corrcoef(arr1,arr2) 协方差矩阵

  10. convolve 移动值移动平均值

    np.convolve(df[‘col2’], np.ones(3)/3, mode=‘valid’)

  11. np.sqrt 开方

    df[[‘salary’]].apply(np.sqrt)

  12. np.sum() 求和

    new.sum(axis=1)

  13. np.mud 余数

  14. np.multiply(a,b) 乘

  15. np.max() 最大值

    1. 注意 行最大 axis=1 列最大 axis =0
  16. np.min() 最小值

  17. np.ptp() 数组沿指定轴返回最大值减去最小值

  18. np.cumsum() 累加值

    1. 逐层累加,返回相同形状的数组

    2. 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)
      
  19. np.cumprod() 累乘积值

    1. 沿指定轴方向进行累乘积

    2. np.cumprod(b,axis=1)
      array([[ 0, 0, 0], 
      	 [ 3, 12, 60], 
      	 [ 6, 42, 336], 
       [ 9, 90, 990]], dtype=int32)
      
  20. np.dot 矩阵乘法

  21. np.linalg.det 行列式

  22. np.linalg.inv 矩阵求逆

  23. np.linalg.svd() 矩阵SVD分解

  24. np.squeeze(arr) 压缩矩阵

    1. 从数组的形状中删除单维度条目,即把shape中为1的维度去掉

    2. arr = np.random.randint(1,10,[3,1])
      arr
      	[[3]
       [8]
       [5]]
      np.squeeze(arr)
      [3 8 5]
      
  25. np.linalg.solve() 求解线性方程组

    1. 输入:

      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)

增加

  1. np.repeat 重复

    1. 参数:数据、次数、轴向

    2. 数据d的每一行复制3次

      np.repeat(d,3,axis=0)

  2. copy 副本

    1. #对副本数据进行修改,不会影响到原始数据

删除

  1. np.delete 行/列
    1. 参数:数据,位置 行/列的位置,轴向
    2. np.delete(d1,np.unique(np.where(np.isnan(d1))[0]),0)

查询

元素

  1. 索引:值

  2. 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
    
  3. 直接查

    1. 注意是中括号 new[new>1]
  4. np.take根据位置列表查找

    1. 参数:被查数组,位置数组
  5. unique 不同元素(计数)

    1. 相当于 抽取不同的值重赋值
    2. 返回 元组:由数组构成
    3. 参数:
      1. data
      2. axis
      3. return_counts
    4. d=np.unique(d,axis=0) np.unique(d,return_counts=True)
  6. isin 包含

    1. 注意包含和等于的区别:

      包含是有值存在,等于是位置和值都对应

  7. intersect1d 获得相同元素

    1. 类似: np.unique(arr1[np.isin(arr1,arr2)])逐个排查
    2. np.intersect1d(arr1,arr2)
  8. setdiff1d 获得不同元素

    1. 类似:

      arr3 = arr1[~(np.isin(arr1,arr2))]

  9. extract 输出满足条件的数据

    1. np.extract(s>3,s)

位置

  1. np.where 条件判断

    1. 3个参数,分别是判断条件、为真时的值,为假时的值

      1. np.where(s>3,1,-1)# 满足条件的,赋值为1,不满足的赋值为-1,返回的数据长度和s一样
    2. 返回:tuple, 包含各维度数组猜想:按照各个维度分别进行判断,返回符合条件的索引

      1. np.where(c!=b)

        (array([2, 2]), array([2, 3]))

  2. np.argwhere 位置

    1. 返回值:二维组对象,包含所有对象(符合条件)的位置
    2. np.argwhere(df[‘col1’] % 5==0)
  3. argmax 位置

    1. 参数 axis , 默认是 0,表示第几维的最大值
  4. argmin位置

  5. argsort 位置

    1. 返回的是数据中, 从小到大的索引值
      • argsort返回的是排完序以后,在原数据中的索引位置
      • 返回的是数据中,从小到大的索引值

空行/值

  1. np.isnan 判断空值
  2. any嵌套 空行

数据类型/维度

  1. issubdtype数据类型判断\数组属性
  2. ndim 维度

数字

  1. np.nan 空值

    1. d1[d1<10]=np.nan
  2. n’p.sort() 排序

    1. 参数含义
      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)

  3. astype 数组 成指定类型

    1. b.astype(float)

      array([[ 0., 1., 20., 3., 4., 5.], [ 6., 7., 8., 9., 10., 11.]])

  4. arr1.flags.writeable 权限 只读模式

  5. tolist() 数组转换成 list

    1. b.tolist()

      [[0, 1, 20, 3, 4, 5], [6, 7, 8, 9, 10, 11]]

字符串

  1. 直接拼接 +
  2. np.char.add 字符串无缝拼接
  3. np.char.title 首字符大写

元素格式

  1. np.ceil(arr) 向上取整
  2. np.floor(arr) 向下取整
  3. np.set_printoptions(suppress=True) 取消科学计数

形状

  1. pad 数据环绕

    1. 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]])
      
      
  2. reshape 形状转换

    1. 方法非常灵活地应用于调整数组的大小,但是不改变数组的长度。即长度 100 的数组,你可以非常方便地调整为 1×100 或者是 4×25 或者是 5×20。这点在将横向量调整为列向量的时候非常有用。

    2. 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]])
      
  3. resize() 维度变化

    1. 函数 resize()的作用跟 reshape()类似,但是会改变所作用的数组,相当于有 inplace=True 的效果

    2. b.resize(4,3)
      b 
      array([[ 0, 1, 2], 6[ 3, 4, 5], 7 [ 6, 7, 8], 8 [ 9, 10, 11]])
      
    3. reshape/resize() 两者的区别在于返回拷贝(copy)还是返回视图(view)

  4. b.shape 用 tuple 指定数组的形状

    1. b.shape=(2,6) 
       array([[ 0, 1, 20, 3, 4, 5],  [ 6, 7, 8, 9, 10, 11]])
      
  5. ravel 多维数组转换成一维数组

    1. 而 ravel() 返回的是视图(view),会影响原始矩阵

    2. b.ravel()
      array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
      
  6. flatten 返回一份拷贝

    1. 需要分配新的内存空间,对 拷贝所做的修改不会影响原始矩阵

    2. b.flatten()

      array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])

  7. transpose 转置

    1. 数组转置的属性(T),也可以通过 transpose() 函数来实现

    2. b.transpose()
      array([[ 0, 6],  [ 1, 7],  [20, 8],  [ 3, 9],  [ 4, 10],  [ 5, 11]])
      

堆叠数组

  1. hstack() 水平叠加

  2. 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]])
    
  3. column_stack()水平叠加

    1. 通过设置 axis 的值来设置叠加方向:

      axis=1 时,沿水平方向叠加

      axis=0 时,沿垂直方向叠加

      concatenate()效率更高

    2. np.concatenate((c,b),axis =0)

  4. vstack()
    row_stack() 垂直叠加

  5. concatenate() z综合

  6. append

    1. 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]])]
  1. np.hsplit(b, 2) 沿横向轴拆分(axis=1) / np.split(b,2, axis=1)
  2. np.vsplit(b, 2) 沿纵向轴拆分(axis=0)/ np.split(b,2,axis=0)

数组合并

  1. np.piecewise 数组分类

    1. 参数一 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]
    

文件

读取 txt 文件

  1. np.genfromtxt
  2. dtype=‘int’,delimiter=’,’
  3. np.savetxt 存储至本地
    2. ​ 参数 文件名 数据

pandas

1.简介

  1. 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)
  2. 支持的数据类型:

    默认的数据类型是int64,float64.

    1. float
    2. int
    3. bool
    4. datetime64[ns]
    5. datetime64[ns, tz]
    6. timedelta[ns]
    7. category
    8. object
  3. 数据格式

    1. 一维数组 -Series

      1. 定长的字典序列

        只允许存储相同的数据类型,这样可以更有效的使用内存,提高运算效率

      2. pandas.Series(data,index,dtype,name)。

        data可以为列表,array或者dict。

        index表示索引,必须与数据同长度,name代表对象的名称

        index 和 values。在 Series 结构中,index 默认是 0,1,2,……递增的整数序列,也可以自己指定比如 index=[‘a’, ‘b’, ‘c’, ‘d’]。

      3. 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']
        
    2. 二维的表格型数据结构–DataFrame

      1. 数据框其实就是二维的数据结构,数据分析中最常用

      2. image-20210129105516666
      3. pandas.DataFrame(data,index,dtype,columns)。

      4. data列表 Array dict
        Index行索引列表
        columns列名列表
    3. 三维的数组-Panel

      可以理解为DataFrame的容器

    4. 以时间为索引的Series–Time- Series

2. 数据描述

方法名称说明
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()

3.数据统计

  1. 基本运算

    常用的统计函数,如果遇到空值 NaN,会自动排除

    统计个数count()空值NaN不计算
    值的次数value_counts()
    平均值mean()
    上下值的平均值interpolate()用途**:**将空值用上下值的平均值填充
    最值
    最小值min()
    局部最大值 它前一个与后一个数字的都大的数字
    最小值的索引位置argmin()
    最大值的索引位置argmax()
    最小值的索引值idxmin()
    最大值的索引值dxmax()
    最大值max()
    中位数median()
    总和sum()
    方差var()
    标准差std()
    分位数quantile()
    统计大礼包Describe()
  2. 计算

    -df[“salary”] - df[0]
    diff上下行之间****差值前一天与后一天收盘价的差值 data[‘收盘价(元)’].diff()
    变化率pct_change上下行之间data[‘收盘价(元)’].pct_change()
  3. 数据分组运算

    1. groupby 创建分组对象

    2. 计算项

      单维度分组默认计为分组维度
      多维度分组可以在调用方法时指定对应的组:
      如count、mean 、 median 、 max和min等

    默认计算列
    df[['district','salary']].groupby(by='district').mean()
    指定计算列
    group_2=titanic_pd.groupby(['Sex','Age_Type'])['Fare'].mean()
    	结合agg函数
    
    
  4. 聚合函数使用 agg

    1. 针对分组后的对象, 对各列分别进行计算

    2. 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})
      
      
  5. 分组对象和apply函数

  6. 透视图与

    1. pivot_table 根据行或列对数据绘制

    2. pivot_table( data, index, columns,values, aggfunc, fill_value, margins, margins_name=)

    3. 参数:

      Index : 行分组键

      columns: 列分组键

      values: 分组的字段,只能为数值型变量

      aggfunc: 聚合函数

      margins: 是否需要总计

    4. 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')
      
  7. 交叉表 pd.crosstab

    1. 交叉表用于计算分组频率,计数/百分比分布

    2. pd.crosstab(index,columns,normalize)

    3. 参数:

      Index: 行索引

      Columns: 列索引

      Normalize: 数据对数据进行标准化

      index表示行

      column表示列

    4. b=pd.crosstab(index=df['weekday'],columns=df['discount%'],margins=True,normalize='index')
      
  8. 离散化

    1. 等宽分箱 pd.cut

      1. pandas.cut(x, bins, right=True, labels=None, retbins=False, precision=3, include_lowest=False)

      2. 参数:

        x,类array对象,且必须为一维,待切割的原形式
        bins,整数、序列尺度、或间隔索引。如果bins是一个整数,它定义了x宽度范围内的等宽面元数量,但是在这种情况下,x的范围在每个边上被延长1%,以保证包括x的最小值或最大值。如果bin是序列,它定义了允许非均匀bin宽度的bin边缘。在这种情况下没有x的范围的扩展。
        right,布尔值。是否是左开右闭区间,right=True,左开右闭,right=False,左闭右开
        labels,用作结果箱的标签。必须与结果箱相同长度。如果FALSE,只返回整数指标面元(划分的区间/切割标准)。
        retbins,布尔值。是否返回面元
        precision,整数。返回面元的小数点几位
        include_lowest布尔值。第一个区间的左端点是否包含
      3. bins = [0,5000, 20000, 50000]
        group_names = ['低', '中', '高']
        df['categories'] = pd.cut(df['salary'], bins, labels=group_names)
        
    2. 等频分割 pd.qcut

      1. (x, q, labels=None, retbins=False, precision=3, duplicates=’raise’)

        参数:

        q整数或分位数组成的数组。
        q,整数 或分位数数组 整数比如 4 代表 按照4分位数 进行切割
        labels,用作结果箱的标签。必须与结果箱相同长度。如果FALSE,只返回整数指标面元。

4. 读取文件

pandas内置了10多种数据源读取函数,常见的就是CSV和EXCEL,在运行的过程可能会存在缺少 xlrd 和 openpyxl 包的情况

1.CSV

  1. 读取 read_csv()

    1. 结果为dataframe格式
    2. 名称尽量是英文
    3. 参数:
    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
  2. 写文件 to_csv

    1. pd.to_csv(‘car_complain.csv’, index=False)
    2. 参数:index index=False,表明不保存index
  3. Excel

    1. 读 read_excel
      1. order1=pd.read_excel(‘meal_order_detail.xlsx’,sheet_name=‘meal_order_detail1’)

5. 查询

1. 索引

层次化索引

  1. 查看索引 df.index (索引是可以重复的)
  2. 去重后的索引 df.index.unique()
  3. 索引长度 len(df.index)
  4. 索引 np.where 按照条件筛选,返回的字典格式,需要进一步提取
    1. np.where(rowsums > 60000)[0]

行或者列

  • 基础索引方式,就是直接引用
  • loc[行索引名称或者条件,列索引名称或者标签]
  • iloc[行索引位置,列索引位置]
  1. 基础索引方式,就是直接引用列表

  2. 列表由被引用的列名组成

  3. loc

    1. 通过行索引 “Index” 中的具体值来取行数据,第1个参数都是对行操作。第2个参数是对列。

    2. 条件搜索

    3. 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]]
  4. iloc

筛选位置,通过行号来取行数据

df.iloc[0:5,1:4]

df.iloc[::20, :][[‘薪资水平’]]

隔*行进行一次抽样

  1. take

    f['col1'].take([1,10,15]) 
    
    \# 等价于
    
    df.iloc[[1,10,15],0]
    
  2. 条件查询

    1. 范围 :between

      参数:

      left – Left boundary.
      right – Right boundary.
      inclusive – Include boundaries True/Flase

    2. > & | ~

      1. ~ 取反
    3. 包含:isin

      1. 放回的对象?布尔值?
      2. df[‘cat1’].isin([18,28])
    4. 遍历 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'))
      
    5. 采样 resample

      按周为采样规则,取一周收盘价最大值

      data[‘收盘价(元)’].resample(‘W’).max()

      data[‘收盘价(元)’].resample(‘7D’).max()

元素

  1. 排序 argsort

  2. 判断类型 type

  3. 重复值 duplicated

    逐行判断 默认判断:行之间是否有重复值,返回布尔值df.duplicated()
    展示重复行df[df.duplicated()]
    计数重复行np.sum(df.duplicated())
    删除重复行df.drop_duplicates(subset=[‘Condition’,‘Condition_Desc’,‘Price’,‘Location’],inplace=True)
  4. 日期

    1. 取出年月日,dt方法,datetime64

    dataframe时间戳数据一般为

    1. 查找空值 df.isnull()

      统计缺失比例

      print(**'每行缺失值的统计:'**,df.apply(lambdax:sum(x.isnull())/len(x),axis=0))
      
      **每列数据缺失值**
      
      ata.isnull().sum()
      
    2. 任何值 any

字符串

  1. '**'开头的行 str.startswith

6. 改

索引

  1. reset_index

    1. 还原索引
      重置行号
      重新变为默认的整型索引
    2. df1.reset_index(drop=True,inplace=True)
      inplace = True:不创建新的对象,直接对原始对象进行修改
  2. df.index =[],

    1. 设置新列为索引
    2. 列表的长度必须与df行数一致
      索引可以重复
  3. df.set_index

    1. 将某列设置为索引
    2. drop=False 表示保留原先"YY"列的数据。(默认为True)
      将多列设置为索引,需要[]
  4. swaplevel()

    1. 交换索引先后次序

  1. 改列名rename

    1. 参数,字典
      重命名列名 columns
      重命名行名index
  2. 直接修改列名

    1. 修改列名为****col1,col2,col3

      df.columns = [‘col1’,‘col2’,‘col3’]

  3. 列顺序

    1. 按照要求的顺序读取,重写入
  4. 顺序颠倒

    1. df.ix[:, ::-1]
  5. 数据滑动窗口

    1. rolling

    2. 5日均线:5个数据取均值作为一个数据滑动窗口

      data[‘收盘价(元)’].rolling(5).mean()

  6. 计算移动窗口

    1. expending

    2. 计算开盘价的移动窗口均值

      data[‘开盘价(元)’].expanding(min_periods=1).mean()

  1. 顺序

    1. sort_values ascending:False 降序

      df.sort_values(‘salary’, ascending=False)

  2. 后移 shift

    1. 向后/前移动5行

      data.shift(5)

      data.shift(-5)

  3. 反转df的行

    df.iloc[::-1, :]

数据

  1. 空值填充 df.fillna()

    1. 单列填充

      • 众数:df[‘Exterior_Color’].fillna(df[‘Exterior_Color’].mode()[0],inplace=True)
    2. 多列填充

      • 固定值:df.fillna(value={‘Location’:‘A’,‘Model_Year’:‘6’},inplace=True)
      • 函数:df.fillna(value={‘Warranty’:df[‘Warranty’].mode()[0],‘Model’:df[‘Model’].mode()[0]},inplace=True)
      • 前/后填充:
  2. 直接修改

    1. df.col1

    2. 将第一列大于50的数字修改为’高’

      df.col1[df[‘col1’] > 50]= ‘高’

  3. df.map

    1. data[‘diagnosis’] = data[‘diagnosis’].map({‘M’:1,‘B’:0})

7. 增加

1. 行

  1. 增加 df.append

2. 列

  1. 直接传入 df[‘New’]

    titanic_pd[‘Family_Size’]=titanic_pd[‘SibSp’]+titanic_pd[‘Parch’]

  2. 插入 df.insert

    1. insert(loc: int, column: Any, value: Any,allow_duplicates: Any = False)

      loc:int,插入的位置。
      column:Any列名
      value:Any插入的数据。
      allow_duplicates:Any = False
    2. df.insert(0,‘auction_id’,auction_id)

8. 删除

  1. drop

    • drop(labels,axis,inplace=True)
    labelsIndex labels to drop.
    axisRedundant for application on Series. axis表示作用轴:axis =1 按列删除 axis = 0 按照行
    indexRedundant for application on Series, but ‘index’ can be used instead of ‘labels’.
    columnsNo change is made to the Series; use ‘index’ or ‘labels’ instead.
    levelFor MultiIndex, level for which the labels will be removed.
    inplaceIf True, do operation inplace and return None. inplace=True表示是否对原数据生效 ,
    errorsIf ‘ignore’, suppress error and only existing labels are dropped.

  1. del

    1. 去掉重复的值
  2. drop_duplicates()函数

    1. 可以通过SQL中关键字distinct的用法来理解,根据指定的字段对数据集进行去重处理。
    2. 用法:
      DataFrame.drop_duplicates(subset=None, keep=‘first’, inplace=False)
    3. 参数说明
    参数说明
    subset根据指定的列名进行去重,默认整个数据集
    keep可选{‘first’, ‘last’, False},默认first,即默认保留第一次出现的重复值,并删去其他重复的数据,False是指删去所有重复数据。
    inplace是否对数据集本身进行修改,默认False

  1. 空值 df.dropna()

    1. parameters详解
      axisdefault 0指行,1为列
      how{‘any’, ‘all’}, default ‘any’指带缺失值的所有行;'all’指清除全是缺失值的行
      threshint,保留含有int个非空值的行
      subset对特定的列进行缺失值删除处理
      inplace这个很常见,True表示就地更改
  2. 字符串

    1. 去空格

      去空格
      删除两边空格 特定字符strip
      #删除左边空格lstrip
      #删除右边空格rstrip

9. 转化

索引

  1. 转换成列表类型 list(df.index)

  1. 列转换为list to_list() df[‘grammer’].to_list()

  2. 合并为一列 + 数据类型需要相同 df[“test1”] = df[“salary”].map(str) + df[‘education’]

  3. 文本格式转换为日期格式

    1. to_datetime()

      df[‘New_day’]=pd.to_datetime(df[‘day’],format=’%Y%m%d’)

    2. to_pydatetime()

    3. timedelta

      1. 时间差数据:转换为指定时间单位的数值。

        df[‘时间差’]=df[‘time_diff’]/pd.Timedelta(‘1 D’)

      2. 利用除法
        类似的 Y M D H m

  4. 数据格式 astype

    df[‘time_diff’].astype(‘timedelta64[Y]’)
    ‘timedelta64[Y]’ df2[‘Chinese’].astype(‘str’)
    df2[‘Chinese’].astype(np.int64) ‘str’

  5. 取消使用科学计数法 df.round(3)

  6. 转换为百分数 format df.style.format({‘data’: ‘{0:.2%}’.format})

字符串

  1. 大小写转换 提取

    str Pandas中提供了字符串的函数,但只能对字符型变量进行使用 ,
    通过str方法访问相关属性 ,可以使用字符串的相关方法进行数据处理

  2. 全部大写 str.upper() df2.columns.str.upper()

  3. 全部小写 str.lower() df2.columns = df2.columns.str.lower()

  4. 首字母大写 str.title() df2.columns = df2.columns.str.title()

  5. 按字符位置提取 str[1:] f1[‘Price_1’]=df1[‘Price’].str[1:]

  6. 替换字符 str.replace df1[‘Price_1’]=df1[‘Price_1’].str.replace(r’,’,’’)

  7. 时间转换为月-日 strftime df.ix[i,0].to_pydatetime().strftime("%m-%d")

  8. 拆分 str.split

10 .表间操作

数据表合并 连接前确保对应字段的数据类型的一致性

  1. merge

    1. 参数

      left: 数据1Any,
      right: 数据2Any,
      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)
    2. 案例

      1. 内联接

        df_2=pd.merge(left=df,right=df1,how=‘inner’,left_on=‘user_id’,right_on=‘user_id’)

      2. 使用merge通过索引合并两个Dataframe

        df2 = df.merge(df2, left_index=True, right_index=True, how=‘left’)

  2. concat

    一般用作相同结构的表行合并,多张表合并可以建立循环

    1. 参数

      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
    2. 案例

      1. 两张表合并

        basic=pd.concat([basic,basic_i],axis=0,ignore_index=True)

      2. 第一行与最后一行拼接

        pd.concat([df[:1], df[-2:-1]])

11.清洗函数

  1. 利用高阶函数处理数据

    1. Thinking: apply和map的区别是什么?

      • apply 用在dataframe上,用于对row或者 column进行计算

      • applymap 用于dataframe上,是元素级别的操 作

      • map ,是python自带的,用于series上,是元 素级别的操

  2. 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],'**'))
    
    
    
  3. map

    专门用来映射

    字典
    df2['sex']=df2['gender'].map({'0':'girl','1':'boy','2':'unkonwn'})
    自定函数
    df2['sex']=df2['gender'].map(sex_set)
    

12其他

  • 数据展示两行代码要加载打印语句的前面,否则没有效果 pd.set_optionpd.set_option(‘display.max_columns’,None)#显示完整的列
    pd.set_option(‘display.max_rows’,None)#显示完整的行
    版本pd.version
    explodDataFrame.explode(self, column: Union[str, Tuple]) 参数作用: column :str或tuple

sklearn

matplotlib

NTLK 英文文档处理包

what英文文档处理包import nltk
#分词nltk.word_tokenize(text)word_list = nltk.word_tokenize(text)
#标注单词的词性nltk.pos_tag(word_list)nltk.pos_tag(word_list)

jieba 中文文档处理包

#中文分词jieba.cut (text)word_list = jieba.cut (text)

待解决

  • jupter 操作
已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 1024 设计师:白松林 返回首页