Python
python是一种简单的、解释型的、交互式的、可移植的、面向对象的超高级语言。语法清晰,适合多种操作系统。python有一个交互式的开发环境,因为是解释运行,大大节省了每次编译的时间,语法简单,内置多种高级数据结构,如字典、列表等。python具有大部分面向对象语言的特征,可完全进行面向对象编程。
python程序运行原理:当python运行脚本时,在代码开始进行处理之前,先将其编译成字节码,然后将其转发到所谓的“虚拟机”中。当程序执行时,python内部先将源代码编译成字节码的形式。字节码是底层的、与平台无关的表现形式。概括来讲就是,python通过把每一条源语句分解为单一步骤来将这些源语句翻译成一组字节码指令。这些字节码指令可以提高速度。python虚拟机就是迭代运行字节码的一个大循环,一个接一个地完成操作。PVM是python的运动引擎,它时常表现为python系统的一部分,并且它是实际运行脚本文件的组件。从技术来讲,它是运行python的最后一步。
python的传统运行执行模式:录入的源代码转换为字节码,之后字节码在python虚拟机中运行。代码自动被编译,之后再解释。
IDLE常用快捷键
快捷键 | 说明 |
Alt+N Alt+P | 查看历史命令上一条、下一条 |
Ctrl+F6 | 重启shell,以前定义的变量全部失效 |
F1 | 打开帮助文档 |
Alt+/ | 自动补全前面曾经出现过的单词 |
Ctrl+[ Ctrl+] | 缩进代码和取消缩进 |
Alt+M | 打开模块代码,先选中模块,然后按下此快捷键,会帮助你打开改模块的py源码供浏览 |
Alt+C | 打开类浏览器,方便在源码文件中的各个方法体之间切换 |
F5 | 运行程序 |
python程序的构成
1、Python程序由模块构成。一个模块对应python源文件,一般后缀名是:.py;
2、模块由语句构成。运行Python程序时,按照模块中语句的顺序依次执行;
3、语句是Python程序的构造单元,用于创建对象、变量赋值、调用函数、控制语句等。
python文件的创建和执行
交互式环境每次只执行一条语句;为了编写多条语句实现复杂逻辑需要创建Python文件。
在IDLE中创建:File--->new创建Python文件,并可以编辑该文件内容;
执行:快捷键F5或者点击Run-->Run module。
图形化程序设计
Task:绘制奥运五环
import turtle
turtle.width(10)
turtle.color('blue')
turtle.circle(50)
turtle.penup()
turtle.goto(120,0)
turtle.pendown()
turtle.color('black')
turtle.circle(50)
turtle.penup()
turtle.goto(240,0)
turtle.pendown()
turtle.color('red')
turtle.circle(50)
turtle.penup()
turtle.goto(60,-50)
turtle.pendown()
turtle.color('green')
turtle.circle(50)
turtle.penup()
turtle.goto(180,-50)
turtle.pendown()
turtle.color('yellow')
turtle.circle(50)
from turtle import *
color('red','yellow')
begin_fill()
while True:
fd(200) #forward()
lt(170) #left()
if abs(pos())<1:
break
end_fill()
done()
代码缩进:通过缩进组织代码块,采用“四个空格”表示一个缩进。tab制表符就是4个空格。
使用注释 #
行连接符 \
>>> b="abcv\
efgh\
fgg"
>>> b
'abcvefghfgg'
对象
Python中,一切皆对象。每个对象由:标识(identity)、类型(type)、值(value)组成。
对象的本质就是:一个内存块,拥有特定的值,支持特定类型的相关操作。
引用
在python中,变量也称为:对象的引用。因为,变量存储的就是对象的地址。
变量通过地址引用了“对象”。
变量位于:栈内存
对象位于:堆内存
Python是动态类型语言
变量不需要显式声明类型。根据变量引用的对象,Python解释器自动确定数据类型。
Python是强制类型语言
每个对象都有数据类型,只支持该类型支持的操作。
标识符
用于变量、函数、类、模块等的名称。
1、区分大小写
2、第一个必须是字母或者下划线,其后是字母、数字或者下划线
3、不能使用关键字
4、以双下划线开头和结尾的名称通常有特殊含义,尽量避免这种写法
变量的声明、初始化以及删除
如果对象没有变量引用,就会被垃圾回收器回收,清空内存空间
链式赋值、系列解包赋值
eg:交换数据
常量:Python不支持常量,只能在逻辑上进行控制。
内置数据类型
整型、浮点型、布尔型及字符串型
注:区别整数除法和小数除法
直接获取商和余数的函数
divmod返回的是一个元组,第一个元素代表商,第二个元素代表余数。
整数
二进制 0b或0B 0 1
八进制 0o或0O 0 1 2 3 4 5 6 7
十进制 0 1 2 3 4 5 6 7 8 9
十六进制 0x或0X 0 1 2 3 4 5 6 7 8 9 a b c d e f
python2.X中可以存储±2^31,python3.X无限制
浮点数
四舍五入
增强型赋值运算符
+=、-=、*=、/=、//=、**=、%=
时间表示
计算机的时间表示是从“1970年1月1日00:00:00”开始,以毫秒(1/1000秒)进行计算,将1970年这个时刻称为“unix时间点”
返回的值以秒为单位,小数部分是微秒
Task: 定义多点坐标、绘制折线、计算起始点和终点的距离
布尔值:true、false
python2中没有布尔值,直接用数字0表示False,用数字1表示True
python3中,把True和False定义成关键字,但它们的本质还是1和0,甚至可以和数字相加
比较运算符
所有比较运算符返回1表示真,返回0表示假。这分别与特殊的变量True和False等价。
== != > < >= <= or and not
同一运算符
同一运算符用于比较两个对象的存储单元,实际比较的是对象的地址。
is 判断两个标识符是不是引用同一个对象
is not 判断两个标识符是不是引用不同对象
is与==的区别:
is 用于判断两个边路引用对象是否为同一个,即比较对象的地址
==用于判断引用变量引用对象的值是否相等,默认调用对象的_eq()_()方法
字符串
字符串基本特点
字符串的本质是:字符序列。Python的字符是不可改变的,我们无法对元字符串做任何修改。但,可以将字符串的一部分复制到新创建的字符串,达到“看起来修改”的效果。
Python不支持单字符类型,单字符类型也是作为一个字符串使用。
字符串编码
Python3直接支持Unicode,可以表示世界上任何书面语言的字符。Python3的字符默认就是16位的Unicode编码,ASCII码是Unicode编码的子集。
Unicode(2^16) ASCII(2^8)
使用内置函数ord()可以把字符转换成对应的Unicode码;
使用位置函数chr()可以把十进制数字转换为对应的字符。
引号创建字符串
可以通过单引号或者双引号创建字符串
使用两种引号的好处是可以创建本身就包含引号的字符串,而不使用转义字符。
连续三个单引号或三个双引号,可以帮助我们创建多行字符串。
空字符串和len()函数
python允许空字符串的存在,不包含任何字符;
len()用于计算字符串含有多少字符。
转义字符
可以使用“\+特殊字符”,实现某些难以用字符表示的效果。比如:换行等。常见的转义字符有:
转义字符 | 描述 |
\(在行尾处) | 续行符 |
\\ | 反斜杠符号 |
\‘ | 单引号 |
\“ | 双引号 |
\b | 退格(backspace) |
\n | 换行 |
\t | 横向制表符 |
\r | 回车 |
字符串拼接
1、可以使用+将多个字符串拼接起来:如果两边都是字符串,则拼接;如果两边都是加法运算,则执行加法运算;如果两边类型不同,则抛出异常。
2、可以将多个字符串直接放到一起实现拼接。
字符串复制
使用*可以实现字符串复制
换行打印
不换行打印
调用print()时,会自动打印一个换行符。若不想换行,可通过参数end="任意字符串",实现末尾添加任何内容:
从控制台读取字符串
str()实现数字转换字符串
使用[]提取字符
字符串的本质就是字符序列。可以通过在字符串后面添加[],在[]里面指定偏移量,可以提取该位置的单个字符。
正向搜索:
最左侧第一个字符,偏移量为0,第二个偏移量是1,以此类推。直到len(str)-1为止。
反向搜索:
最右侧第一个字符,偏移量是-1,导数第二个偏移量是-2,以此类推,直到-len(str)为止。
replace()实现字符串替换
字符串是“不可变的”,我们可以通过[]获取字符串指定位置的字符,但是我们不能改变字符串。
原来的a没有改变!!!!
字符串切片slice
切片slice可以快速提取子字符串,标准格式为: [起始偏移量start : 终止偏移量end : 步长step]
左闭右开区间,包头去尾
操作 | 说明 |
[:] | 提取整个字符串 |
[start:] | 从start索引开始到结尾 |
[:end] | 从头开始直到结尾 |
[start:end] | 从start到end-1 |
[start:end:step] | 从start到end-1,步长为step |
其他操作:负数操作
Task: 1、将to be or not to be倒序输出
2、将“sxtsxtsxtsxtsxt”字符串中所有的s输出
字符串分割split()、合并join()
split()可以基于指定分隔符字符串分割成多个子字符串(存储到列表中)。如果不指定分隔符,则默认使用空白字符(换行符/空格/制表符)
join()的作用和split()作用相反,用于将一系列子字符串连接起来。
拼接字符串要点:使用字符串拼接符+,会生成新的字符串对象,因此不推荐使用+来拼接字符串。推荐使用join函数,因为join函数在拼接字符串之前会计算所有字符串的长度,然后逐一拷贝,仅新建一次对象。
字符串驻留机制和字符串同一性判断
字符串驻留和比较
字符串驻留:仅保存一份相同且不可变字符串的方法,不同的值被存放在字符串驻留池中。Python支持字符串驻留机制,对于符合标识符规则的字符串(仅包含下划线(_)、字母和数字)会启用字符串驻留机制。
直接使用==,!=对字符串进行比较,是否含有相同的字符
使用is/ not is,判断两个对象是否一个对象,比较的是对象的地址,即id(obj1)是否和id(obj2)相等。
成员操作符
in/not in关键字,判断某个字符(子字符串)是否存在于字符串中。
字符串常用方法汇总
方法 | 说明 |
len(a) | 字符串长度 |
a.startwith("aaaaa") | 以指定字符串开头(boolean) |
a.endwith("dddddd") | 以指定字符串结尾(boolean) |
a.find("aaa") | 第一次出现指定字符串的位置 |
a.rfind("aaa") | 最后一次出现指定字符串的位置 |
a.count("aa") | 指定字符出现了几次 |
a.isalnum | 所有字符全是字母或数字(boolean) |
去除首尾信息
可以通过strip()去除字符串首尾指定信息,通过lstrip()去除字符串左边指定信息,通过rstrip()去除字符串右边指定信息。
大小写转换
编程中的字符大小写转换相关方法汇总如下:
示例 | 说明 |
a.capitalize() | 产生新的字符串,首字母大写 |
a.title() | 产生新的字符串,每个单词都首字母大写 |
a.upper() | 产生新的字符串,所有字符全部大写 |
a.lower() | 产生新的字符串,所有字符全部小写 |
a.swapcase() | 产生新的字符串,所有字母大小写转换 |
格式排版
center()、ljust()、rjust()这三个函数用于对字符串实现排版。
其他方法
函数 | 说明 |
isalnum() | 是否为字母或数字 |
isalpha() | 检测字符串是否由字母组成(含汉字) |
isdigit() | 检测字符串是否由数字组成 |
isspace() | 检测是否为空白符 |
isupper() | 是否为大写字母 |
islower() | 是否为小写字母 |
字符串format格式化、数字格式化操作
python2.6开始,新增了一种格式化字符串的函数str.format(),它增强了字符串格式化的功能。
基本语法是通过{}和:来代替以前的%。
format函数可以接受无限个参数,位置可以不按顺序。
可通过{索引}/{参数名},直接映射参数值,实现对字符串的格式化,非常方便。
注意:如果按照0、1、2......这样的索引进行映射,后面的format应该对应起来,但是按照参数名赋值就不需要有对应的顺序。
填充与对齐
填充常与对齐一起使用。^、<、>分别是居中,左对齐和右对齐,后面带宽度。
: 后面带填充的字符,只能是一个字符,不指定的话默认为空格。
数字格式化
浮点数通过f,整数通过d进行需要的格式化,案例如下:
其他格式供参考
可变字符串
在python中,字符串属于不可变对象,不支持原地修改,如果需要修改其中的值,只能创建新的字符串对象。但是,经常我们确实需要原地修改字符串,可以使用io.StringIO对象或array模块。
运算符总结
1、比较运算符可连用。
2、位操作
3、加法操作
(1)数字相加
(2)字符串拼接
(3)列表、元组等合并
4、乘法操作
(1)数字相乘
(2)字符串复制
(3)列表、元组等复制
复合赋值运算符
复合赋值可以让程序更加精炼,提高效率。
注意:与 C 和 JAVA 不一样,Python 不支持自增(++)和自减(--)
运算符优先级(下表中由高到低)
乘除优先加减;位运算和算数运算>比较运算符>赋值运算符>逻辑运算符。
序列
序列是一种数据存储方式,用来存储一系列的数据。在内存中,序列就是一块用来存放多个值得连续的内存空间。
列表:用于存储任意数目、任意类型的数据集合
列表是内置可变序列,是包含多个元素的有序连续的内存空间。列表定义的标准语法格式为:
a=[10,20,30,40]
列表中的元素类型可以不同。
python中的列表大小可变,可根据需要随时增加或缩小。
字符串和列表都是序列类型,一个字符串是一个字符序列,一个列表是任何元素的序列。
创建列表的4种方式
1、基本语法[]创建
可创建一个空列表
2、list()创建
3、range()创建整数列表 list(range(start,end,step))
start 参数:可选,表示起始数字。默认是 0
end 参数:必选,表示结尾数字。
step 参数:可选,表示步长,默认为 1
python3 中 range()返回的是一个 range 对象,而不是列表。我们需要通过 list()方法将其转换成列表对象。
4、推导式生成列表
列表元素的增加和删除
当列表增加和删除元素时,列表会自动进行内存管理,大大减少了程序员的负担。但这个特点涉及列表元素的大量移动,效率较低。除非必要,我们一般只在列表的尾部添加元素或删除元素,这会大大提高列表的操作效率。
append()方法
原地修改列表对象,是真正的列表尾部添加新的元素,速度最快,推荐使用。
+运算符操作
并不是真正的尾部添加元素,而是创建新的列表对象:将原列表的元素和新列表的元素一次复制到新的列表对象中。这样,会涉及大量的赋值操作,对于操作大量元素不建议使用。
extend()方法
将目标列表的所有元素添加到本列表的尾部,属于原地操作,不创建新的列表对象。
insert()插入元素
使用insert()方法可以将指定的元素插入到列表对象的任意指定位置。这样会让插入位置后面的元素进行移动,会影响处理速度。涉及大量元素时,尽量避免使用。类似这种移动的函数还有:remove()、pop()、del(),它们在删除非尾部元素时也会发生操作位置后面元素的移动。
乘法扩展
使用乘法扩展列表,生成一个新列表,新列表元素是原列表元素的多次重复。
适用于乘法操作的,还有:字符串、元组。
列表元素的删除
del删除
删除列表指定位置的元素
pop()方法
pop()删除并返回指定位置元素,如果未指定位置则默认操作列表最后一个元素。
remove()方法
删除首次出现的指定元素,如不存在该元素抛出异常
列表元素的访问和计数
通过索引直接访问元素
index()获得指定元素在列表中首次出现的索引,语法是:index(value,[satrt,[end]]),其中,start和end制定了搜索的范围。
count()获得指定元素在列表中出现的次数
len()返回列表长度,即列表中包含元素的个数。
成员资格判断
判断列表中是否存在指定的元素,我们使用cout()方法,返回0则表示不存在,返回大于0则表示存在。但是,一般我们会使用更加简洁的in关键字来判断,直接返回True或False。
切片操作
切片是python序列极其重要的操作,适用于列表、元组、字符串等等。
[起始偏移量start: 终止偏移量 end[:步长 step]]
注:当步长省略时顺便可以省略第二个冒号
切片操作时,起始偏移和终止偏移量不在[0,字符串长度-1]这个范围,也不会报错。起始偏移量小于0则会当做0,终止偏移量大于“长度-1”会被当成长度-1。例如:
30超出索引值,没有报错!!!!!!!!
列表的遍历
for obj in listObj
print(obj)
列表排序
修改原列表,不建立新列表的排序
列表排序reversed逆序
reversed()返回迭代器
内置函数 reversed()也支持进行逆序排列,与列表对象 reverse()方法不同的是,内置函数reversed()不对原列表做任何修改,只是返回一个逆序排列的迭代器对象。
reversed返回的迭代器只能用一次!!!!!!!!!!!
其他函数 max、min、sum
sum函数对非数值型列表抛出异常!!!
多维列表
二维列表
一维列表可以帮助我们存储一维、线性数据。 [10,20,30,40]
二维列表可以帮助我们存储二维、表格的数据。
利用嵌套循环进行二维列表打印
元组tuple
列表属于可变序列,可任意修改列表中的元素。元组属于不可变序列,不能修改元组中的元素。因此,元组没有增加元素、修改元素、删除元素的相关方法。
因此,我们只需要学习元组的创建和删除,元组中的元素的访问和计数即可,元组支持一下操作:
1、索引访问
2、切片操作
3、连接操作
4、成员关系操作
5、比较运算操作
6、计数:元组长度len()、最大值max()、最小值min()、求和sum()等
元组的创建
1、通过()创建元组,小括号可省略
如果元组只有一个元素,则必须后面加上括号,这是因为解释器会把(1)解释为1,(1,)解释为元组。
2、通过tuple()创建元组
tuple(可迭代对象)
总结:
tupel()可以接手列表、字符串、其他序列类型、迭代器等生成元组。
list()可以接收元组、字符串、其他序列类型、迭代器等生成列表。
元组的元素访问和计数
1、元组的元素不能修改
修改元组中的元素报错!!!!!!!!
2、元组的元素访问和列表一样,只不过返回的仍然是元组对象。
3、列表关于排序的方法list.sort()是修改原列表对象,元组没有该方法。如果要对元组排序,只能使用内置函数sorted(tupleObj) ,并生成新的列表对象。
zip
zip(列表1,列表2,...)将多个列表对应位置的元素组合成元组,并返回zip这个对象。
生成器推导式创建元组
从形式上看,生成器推导式与列表推导式类似,只是生成器推导式使用小括号。列表推导式直接生成列表对象,生成器推导式生成的不是列表也不是元组,而是一个生成器对象。
我们可以通过生成器对象,转化成列表或者元组。也可以使用生成器对象的__next__()方法进行遍历,或者直接作为迭代器对象来使用。不管什么方式使用,元素访问结束后,如果需要重新访问其中的元素,必须重新创建该生成器对象。
元组总结
1、元组的核心特点是:不可变序列。
2、元组的访问和处理速度比列表快。
3、与整数和字符串一样,元组可以作为字典的键,列表则永远不能作为字典的键使用。
字典
字典是“键值对”的无序可变序列,字典中的每个元素都是一个“键值对”,包含:“键对象”和“值对象”。可以通过“键对象”实现快速获取、删除、更新对应的“值对象”。
列表中我们通过“下标数字”找到对应的对象。字典中通过“键对象”找到对应的“值对象”。“键”是任意的不可变数据,比如:整数、浮点数、字符串、元组。但是:列表、字典、集合这些可变对象,不能作为“键”。并且“键”不可重复。
“值”可以是任意的数据,并且可重复。
一个典型的字典定义方式为:
字典的创建
1、通过{}、dict()来创建字典对象。
创建空的字典对象
2、通过zip()创建字典对象
3、通过frontkeys创建值为空的字典
字典元素的访问
为了测试各种方法,首先设定一个字典对象
1、通过键值获得,若键值不存在则抛出异常;
2、通过get()方法获得“值”,推荐使用。邮电:指定键不存在时,返回None值,也可以设定指定键不存在时默认返回的对象。
推荐使用get()获取“值对象”;
3、列出所有的键值对
4、列出所有的键,列出所有的值。
5、len()键值对的个数
6、 检测一个“键”是否在字典中
字典元素添加、修改和删除
1. 给字典新增“键值对”。如果“键”已经存在,则覆盖旧的键值对;如果“键”不存在,则新增“键值对”。
2、使用 update()将新字典中所有键值对全部添加到旧字典对象上。如果 key 有重复,则直接覆盖。
3. 字典中元素的删除,可以使用 del()方法;或者 clear()删除所有键值对;pop()删除指定键值对,并返回对应的“值对象”;
4、 popitem() :随机删除和返回该键值对。字典是“无序可变序列”,因此没有第一个元素、最后一个元素的概念;popitem 弹出随机的项,因为字典并没有"最后的元素"或者其他有关顺序的概念。若想一个接一个地移除并处理项,这个方法就非常有效(因为不用首先获取键的列表)。
可将字典变为空字典
序列解包
序列解包可以用于元组、列表、字典。序列解包可以让我们方便的对多个变量赋值。
序列解包用于字典时,默认是对“键”进行操作; 如果需要对键值对操作,则需要使用items();如果需要对“值”进行操作,则需要使用 values();
表格数据使用字典和列表存储,并实现访问
字典核心底层原理(重要)
字典对象的核心是散列表。散列表是一个稀疏数组(总是有空白元素的数组),数组的每个单元叫做bucket。每个bucket有两部分:一个是键对象的引用,一个是值对象的引用。
由于所有bucket的结构和大小一致,我们可以通过偏移量来读取指定bucket。
将一个键值对放进字典的底层过程
假设字典a对象创建完后,数组长度为8:
我们要把“name”="XUPT"这个键值对放到字典对象a中,首先第一步需要计算键“name”的散列值。Python中可以通过hash()来计算。
由于数组长度为8,我们可以拿计算出的散列值的最右边3位数字作为偏移量,即“100”,十进制是数字4,对应的bucket检查是否为空。如果为空,将键值对放进去。如果不为空,则依次取右边3位作为偏移量,即"110",十进制是数字6,在查看偏移量为6的bucket是否为空。直到找到为空的bucket将键值对放进去。
python 会根据散列表的拥挤程度扩容。“扩容”指的是:创造更大的数组,将原有内容拷贝到新数组中。
如果有2/3的bucket已经被占用,那么需要进行扩容再将元素添加到字典中。
根据键查找“键值对”的底层过程
当我们调用a.get('name'),然后根据键“name”查找“键值对”,从而找到值对象“XUPT”
第一步,我们仍然要计算"name"对象的散列值:
和存储的底层流程算法一致,也是一次取散列值的不同位置的数字。假设数组长度为8,我们可以拿计算出的散列值的最右边3位数字作为偏移量,即“100”,十进制是数字4。我们查看偏移量4,对应的bucket是否为空。如果为空,则返回None。如果不为空,则将这个bucket的键对象计算对应散列值,和我们的散列值进行比较,如果相等,则将对应的“值对象”返回。如果不相等,则再依次取其他几位数,重新计算偏移量。依次取完后,仍然没有找到。则返回None。
用法总结:
1、键必须可散列
(1)数字、字符串、元组都是可散列的。
(2)自定义对象需要支持一下三点:
①支持hash()函数;
②支持通过__eq__()方法检测相等性;
③若a==b为真,则hash(a)==hash(b)也为真。
2、字典在内存中开销很大,典型的空间换时间;
3、键查询速度很快;
4、往字典里面添加新键可能导致扩容,导致散列表中键的次序变化。因此,不要在遍历字典的同时进行字典的修改。
集合
集合是无序可变,元素不能重复。实际上,集合底层是字典实现,集合的所有元素都是字典中的“键对象”,因此是不能重复的且唯一的。
集合创建和删除
1、使用{}创建集合对象,并用add()方法添加元素
2、使用set(),将列表、元组可迭代对象转换成集合。如果原来数据存在重复数据,则只保留一个。
3、remove()删除指定元素;clear()清空整个集合
集合相关操作
Python对集合提供了并集、交集、差集等运算。