1.2 python简介
Python简介
编程语言分类
- 机器语言:计算机能够理解的二进制代码,通过高低电频的变化实现的(执行效率最高,开发效率低,跨平台性差)
- 汇编语言:用英文符号代替二进制代码,但是依旧是直接操作硬件 ,贴近计算机硬件,是一种低级语言(执行效率高,开发效率低,跨平台性差)
-
高级语言:用人类能够理解的符号来编写程序,高级语言直接调用的是操作系统,而不是直接操作硬件(执行效率低,开发效率高,跨平台型强)
高级编程语言的分类方法:
编译型和解释型:
编译型语言:将程序一次性转换成计算机能理解的二进制语言,执行效率高,开发效率差,跨平台性差
解释性语言:没写完一行指令就转换成中间格式(字节码),解释一行执行一行,执行效率低,但是开发效率高,跨平台性强
混合型:例如Java语言
强类型和弱类型:
强类型:数据类型不可以被忽略的语言,即变量的数据类型一旦被定义,那就不会再改变,除非进行强转。 在python中,例如:name = '奇点',这个变量name在被赋值的那一刻,数据类型就被确定死了,是字符型,值为'奇点'。
弱类型:数据类型可以被忽略的语言,比如linux中的shell中定义一个变量,是随着调用方式的不同,数据类型可随意切换的那种。
总结:Python是一门解释型的强类型的语言
Python语言的特点
- 编程语言是用来定义计算机程序的语言,用来向计算机发出指令。
- python是一种面向对象的解释型计算机程序设计语言。
- 创作者:Guido von Rossum(龟叔)荷兰人,python语言的创造者。
运行python代码的两种方式
- 交互式:即时得到程序的运行结果,多用于调试
- 脚本的方式:将程序写到文件中,然后用python解释器运行(python2.7 Python文件的路径)
python程序运行的三个步骤
- 先启动Python解释器
- 解释器会发送系统套用,将文件中的内容从硬盘存入内存,此时文件中的字符是普通字符,没有语法意义
-
解释器开始解释执行存入的代码,并开始执行语法
文本编辑器编辑文件的过程(对比)
- 首先打开文本编辑器
- 文本编辑器发送系统调用,将文件内容从硬盘读入到内存中
-
文本编辑器会将刚刚读入的内容直接输出在屏幕上,让用户看到结果
前两步内容差不多,第三个阶段不同而已,文本编辑器不会对python代码进行检查和执行,知识进行显示
集成开发环境、虚拟环境
- IDE全称Integrated Development Environment,即集成开发环境,这里选的是pycharm
- 虚拟环境:就是一个新的解释器页面(有点像微信双开)
第一行代码
print('hello world')
# 没啥说的 print是一个打印函数,显示相应的内容
常见问题(bug)
- 命名错误:NameError
- 缩进错误:IndentationError
- 语法错误:SyntaxError
debug(调试模式)
断点调试,从控制台(console)进行控制。
注释
print('你好') # 这里是一个注释,单行的注释(规范:如果写在同行代码的后面,格式应该是空二格井号空一格注释内容),注释是对关键代码进行注释,不是全部都需要注释
'''
这里是多行的注释
是不是很神奇
'''
快捷键ctrl+/
- 可以用注释进行代码的调,备注是的代码是不会被执行的
- 对代码的解释说明
- 记录工作日志 # TODO 注释的内容,这样会在TODO列表中找到需要做的注释,类似于备忘录。
- 通过注释进行聊天(几乎接触不到)
代码规范书写--代码换行
显示超长行处理:
- 在连续书写内容空格位置敲回车,会自动补入一个\,换行显示,表示当前行没有书写完毕。
- 对于连续的独立的内容两端添加(),在括号内就可以任意换行,保持原始输入单元独立即可(就是将整体添加(),()内任意换行,但是该方法不推荐使用)
变量
- 变量是一种变化的量,程序执行的本质上就是一系列状态的变化,变是程序执行的直接体现,所以需要一种机制能够反映或者说是保存下来程序执行时的状态,以及状态的变化,因此出现了变量
- 变量的使用:先定义后引用
- name='奇点' # 定义
- print(name) # 引用
- 变量的内存管理:
- 内存管理:垃圾回收机制,所谓垃圾,就是数据未被变量捆绑,这样就无法访问该数据,就是垃圾
- 引用计数器:就是一个数据关联了很多变量,每多一个变量绑定它,引用计数器就加一,当引用计数器为零时,就变成了垃圾(因为无法通过变量找到这个数据了,就相当于荒废了)
- 引用计数:
-
python解释器自动进行垃圾数据的清理,自动进行内存管理x=10 # 引用计数器加一,为1 y=x # 引用计数器加一,为2 z=y # 引用计数器加一,为3 del x # 引用计数器减一,为2 del y # 引用计数器减一,为1 # 都是相对10这个数据来说的,针对的不是变量
- 变量的命名:遵循PEP8命名规范
- 变量的三大组成部分:
-
变量名:指向等号右侧值得内存地址,用来访问等号右侧的值
命名原则:不要使用拼音,不要使用中文,在见名知意的基础上,尽可能的短,可读性要高,除此之外,还要符合以下原则
数字字母下划线组成
不能以数字开头
不能是python的关键字,会造成关键字的覆盖,导致关键字不能用了
命名风格:
纯小写加下划线的方式birth_age(变量名命名建议这个)
驼峰体:BirthAge
- 赋值符号:将变量的内存地址绑定给变量名
-
变量值:代表记录事物的状态
id:反映的是变量值的内存地址,内存地址不同,id不同——》id(变量名)进行查询
type:不同的值记录不同的状态——》type()
value:代表的是值本身
-
- is和==的区别:
- is是比较左右两个值的身份id是否相同
- ==是比较两个值是否相同
- 值相同,id不一定相同(两块不同的空间可以存储一样的值),id相同,值一定相同
- 小整数池:python解释器启动时,会在内存中申请一系列的空间存放常用的证书,方便python调用,这些整数的范围是-5~256的整数,换句话说-5~256中的整数是一个内存空间,257是另外一个内存空间(可通过python解释器验证)
常量:
在程序运行中不会改变的量,在程序运行中,有些值是固定的,不应该被改变,比如圆周率π
python语法中没有常量的概念,但是程序开发中会涉及常量的概念,所以约定俗成以全大写的变量名为常量
基本数据类型
通过作用、定义、使用方法三个方面来学习
整型int:
就是整数
浮点型float:
就是小数
字符串类型str:
定义:'你好'/"你好"/"""你好"""/'''你好''' 四种定义方法(三连可以多行表示)
字符串中想要显示引号的办法:
内外的引号不一致'abc"d"'
使用转义字符反斜杠'abc\'d\''
字符串之间可以相加,成为字符串的拼接,但是拼接的效率极低,所以不推荐使用
"a"+"b"="ab"
列表类型list:
定义:中括号里面放元素,列表是有序的数据类型——》l=[1,'a',1.1,[1,2,3]]
取值:l[0]——》结果是1
索引对应值,索引从0开始,0代表第一个,索引可以倒数取值,倒数第一个的索引是-1
用途:记录多个值,通过索引精准定位取值
字典类型dict:
定义:key对应值,其中key通常是字符串类型d={'name':'david','age':13},其中key必须是不可变的数据类型,value可以是任意的数据类型
作用:存储多个值,每个值都有唯一一个key与之对应key对值有描述性功能
取值:通过key来取值——》d['name']结果是'david'
字典是没有顺序的数据类型
布尔类型bool:
定义:只有两个值true和false
显式布尔值:就是比较的结果,比如3大于2的结果就是true,或者直接就是true
隐式布尔值:0、空字符串、空列表、空字符串、None代表的是false,其他的数据代表的都是true
作用:记录真假两种状态
可变与不可变类型
可变数据类型:值改变时,id不改变,证明改变的是数据本身,证明原值是可以改变的
list、dict
不可变数据类型:值改变时,id改变,证明产生了新的值,原值没有改变,无法被修改
int、float、str、bool
简单的说,以不可变的数据类型被认为是python中元素的最小单位,不可再被分割引用,但是可变的数据类型,可被看成是一个容器,其中存放的是元素的地址,当元素改变时,改变是其实是里面的元素的地址改变了,可变数据类型本身的地址没变
垃圾回收机制(jc):
Python自带的内存管理机制,主要针对的是内存中的堆区
引用计数:直接引用和间接引用都会将应用计数加一,引用计数为零的数据就是内存垃圾,需被清理
直接引用:指的是从栈区出发直接引用到的内存地址
间接引用:指的是从栈区出发引用到堆区后,在通过进一步引用才能到达的内存地址
容器类数据类型的内存原理:列表在内存中开辟一个空间,存储的是索引和索引对应值的内存地址,然后值的内存地址再指向值,字典的话,存储的就是键和值的内存地址(存的是变量的话,就是变量指向的数据的内存地址)
# 一个例题
x=10
l=[1,2,x] # 相当于存放的是[数据1的内存地址,数据2的内存地址,10的内存地址]
x=123
print(l[2])
# 最后打印的结果还是10,不会改变
标记清除
循环引用:
l1=[111]
l2=[222]
l1.append(l2) # [111的内存地址,l2列表的内存地址]
l2.append(l1) # [222的内存地址,l1列表的内存地址]
# 相互引用,就是循环引用
del l1 # 删除l1的直接引用
del l2 # 删除l2的直接引用
# 一旦将直接引用摘掉之后,还剩下一个间接引用,两个数据都无法被访问到,但是两个数据还都不是垃圾,这样会造成无法清理的垃圾,这就叫内存泄漏
# 如何解决:标记清除
标记清除:
内存中分为很多区,有一个是栈区,栈区存放的是变量名和内存地址的映射关系,一个是堆区,堆区存放的是数据,当存在间接引用时,间接引用的地址都是存放在堆区里面的(上面例子中的[111的内存地址,l2列表的内存地址]全都存放在堆区里面),当删除直接引用之后,还存在间接引用,这时,python解释器会扫描栈区,将栈区中能够直接引用或者间接引用能够访问到的堆区中的数据标记为存活,不能访问的数据标记为非存活对象,应该删除,先标记都清除,所以叫标记清除机制
变量的赋值,传参实际上传递的都是栈区的数据,栈的数据就是变量名与内存地址的对应关系
分代回收
在历经多次扫描的情况下,都没有被回收的变量,gc机制就会认为,该变量是常用变量,gc对其扫描的频率会降低
分代指的是根据存活时间来为变量划分不同等级(也就是不同的代)
新定义的变量,放到新生代这个等级中,假设每隔1分钟扫描新生代一次,如果发现变量依然被引用,那么该对象的权重(权重本质就是个整数)加一,当变量的权重大于某个设定得值(假设为3),会将它移动到更高一级的青春代,青春代的gc扫描的频率低于新生代(扫描时间间隔更长),假设5分钟扫描青春代一次,这样每次gc需要扫描的变量的总个数就变少了,节省了扫描的总时间,接下来,青春代中的对象,也会以同样的方式被移动到老年代中。也就是等级(代)越高,被垃圾回收机制扫描的频率越低
分代回收是为了解决标记清除时反复扫描内存效率低下的问题,是典型的空间换时间(扫描的时候需要记住变量引用次数)
用户交互(输入输出)
-
将结果输出给用户:print()函数
格式化输出:
# 1 %字符串格式化输出 'my name is %s,my age is %s' %('libai','18') # 按位置传值 'my name is %(name)s,my age is %(age)s' %{'name':'libai','age':'18'} # 以字典的形式传值 # %s可以接受任意类型 # %d只能接受数字 # 2 str.format方法 'my name is {},my age is {}' .format('libai','18') # 按照位置传值 'my name is {0},my age is {1}' .format('libai','18') # 按照索引 'my name is {name},my age is {age}' .format(name='libai',age='18') # 按照键值对进行传值 # 格式化显示 'my name is {name=<10}'.format(name='libai') # 表示的含义是共10个字符的长度,name靠左显示,剩下的位置用等号填充,"libai=====",大于号是靠右显示,^是居中显示 'my age is {age:.3f}'.format(age=18.1111111) # 显示的是保留三位小数,处理的方式是四舍五入 # 3 f字符串方法 f'my name is {name},my age is {age}' # 这种方法python3.5以后才有 f'{print('nihao')}'--->nihao f'{10+3}'--->13 # 花括号内的字符串会被当做表达式来运行 # 最快的是第三种,第二种第二快,第一种最慢 # 占位符 # %s :字符串 # %d :整数 # %6d :整数,数字用于设置位数,不足补空白‘ 1234’ # %f :浮点数 # %.4f :设置小数位数,四舍五入,省略数字表示取整1.2000 # %% :输出%
-
接收用户输入:input("请输入你的账号:")函数
python3中输入的内容是字符串
在python2中有一个函数raw_input():用法与input一致,在python2中,input的用法不同,在输入时必须声明数据的类型,输入的数据是什么类型,就存成什么类型的数据
pycharm中的提示性信息
三种波浪线:
- 灰色是显示语法存在错误,但是不影响使用。
- 绿色是单词的拼写可能存在问题,不影响使用。
- 红色是语法的错误,必须要进行修改。
运算符
1.算术运算符
+、-、*、/、//整除、%取余(模运算)、**乘方
优先级与算术运算一致。
2.比较运算符
== | 等于(=是赋值) |
---|---|
!= | 不等于 |
< | 小于 |
> | 大于 |
<= | 小于等于 |
>= | 大于等于 |
字符串的比较运算
==、!=比较的是字符串是不是一致
<、> 等判断时比较的是字符的ASCII码
总的来说就是数字<大写字母<小写字母
当多个字符的时候,比较的原理是第一个和第一个比,再第二个和第二个比……
3.赋值运算符
- 变量的赋值:=
- 增量赋值:a+=1(a=a+1)、-=、*=、/=、**=
- 链式赋值:x=y=z=10(注意是从右向左开始赋值的)
- 交叉赋值:m=10 n=20 交换值 ——》 m,n=n,m
- 解压赋值:l=[1,2,3,4,5,6] a,b,c,d,e,f=l 解压赋值,必须一一对应,当列表元素特别多时用a,b,c,*_=l,abc一一对应,4,5,6三个数据会被星号聚合成列表传递给下划线,下划线接收废弃的数据,但是这种方法只能帮助取两边的值,不能取中间的值(解压字典默认解压的是key)
4.逻辑运算符
- and:与,两者必须同时为真才为真,比较非零数字的时候取后面
- or:或,两者满足一个是真就为真,非零数字比较的时候须选前面
- not:非,就是取反
- 优先级:算术运算>比较运算>not>or>and
- 短路运算:
10>13 and true # 所谓短路运算就是进行逻辑运算时,判断and(或者or)时如果前面是false,就不继续向下判断,直接返回前面的结果false,同理,or运算前面是true的时候,直接返回true,不会继续向下运算
5.成员运算符
in 和 not in:判断元素是否在容器类数据类型中(字符串也可以使用)
6.身份运算符
is :判断id是否相同,如果两个数据的id相同,则一定是相等得(==),但是如果两个数据的值相等,id不一定相同
流程控制:
if判断:
if 条件:
执行的代码内容
# 条件为真,执行代码
# 例如:
a=10
if a>=1 and a<=10: # 条件1
print('大于1')
elif a>10 and a<=100: # 条件2
print('大于10')
elif a>100 and a<1000: # 条件3
print('大于100')
else: # 条件4,else表示的是剩下的所有情况,如果只有两个条件,只用if和else就行了
print('大于1000')
# 嵌套用法
if a>=1 and a<=10:
if a>=5 and a<=10:
print('比5分高')
else:
print('比5分低')
else:
print('比10分高')
while循环:
通常用循环的变量来控制循环的执行次数。
变量一般是从0开始,判断时一般是小于,而不是小于等于。
格式:
while 条件:
反复执行的代码
else:
在while循环结束之后执行的,循环的结束不是在break的情况下结束的
# 举例
i=0
while i<5:
print('hello python')
i+=1
循环的终止与跳出(break与continue)
- break:终止循环,执行循环后面的语句(只跳出本身所在的循环)
- continue:结束本轮循环
- break与continue都必须出现在循环体中,其只能控制本身所在的循环,不能控制其他循环
i=100
while i<1000:
if i//100 == 3:
break
print(i)
i+=1
# 只打印100到299
i=100
while i<1000:
if i//100 == 5:
continue
print(i)
i+=1
# 500-599的内容都不打印
循环终止的另一种方法:改变条件的方式
tag = true
name = input('姓名:')
pwd = input('密码:')
while tag:
if name == 'libai' and pwd == '123':
print('登陆成功')
tag = false
else:
print('请重试')
循环的嵌套
# 理清嵌套的逻辑
i=1
while i<10:
j=1
while j<5:
print(j)
j+=1
print(i)
i+=1
# 对于很多层的嵌套,tag停止循环的方法比break方法要好很多
for循环
for循环在遍历取值上面比while更加的方便
他能够循环打印可迭代对象中的每一个元素
语法:
for i in 可迭代对象: # 可迭代对象包括列表、字典、字符串、元组、集合
循环的代码内容
for i in [1,2,3,'nihao']:
print(i) # 打印列表里面的所有元素
# range()函数
for i in range(0,10,1): # 括号里面的数字依次是起始值,终止值与步长,如果只写一个数字,默认从0开始,实际上就是产生了一个从零开始,步长为一的列表
print(i)
# 打印结果是0到9
在for循环中同样可以使用break、continue和else,效果和while循环中一样
for循环可以嵌套使用
补充:实际上range只是在效果上和列表一样,但是实际上相当于迭代器,比列表更加的节省存储空间
函数介绍print()和len()
print()函数就是打印,需要注意的是,print这个函数是没有返回值的,无法传递给变量,也就是传递给变量之后,显示的结果是none
打印多个对象的时候用逗号隔开就行
end是设置每一行结束之后的标点,默认情况下是换行(end='\n'),这也是为什么两个print的内容默认呈现两行的原因
len()函数是将可迭代对象的长度计算出来
深浅copy
浅copy:
l1=[1,2,3,[1,2]]
l2=l1.copy
# 此时两个列表的id不同
浅copy是将列表内容(列表里面放的是元素索引和元素数据的地址)复制一份给新的列表(新的列表和旧的列表id是不同的),对于列表里面的元素,用的都是一个(简单的来说就是将列表的壳复制了一份,里面装的东西还是一样的)
当需要对列表里面的数据进行改变的时候,可变类型和不可变类型的数据有所不同,不可变的数据类型如果更改(例如将l2列表的1换成100),就直接创建一个新的数据,指向新的数据(例子中的100),原列表(l1)不受影响,但是对于可变的数据类型(例如l2里面的[1,2]),更改里面的数据(将[1,2]里面的2换成200)会直接影响原来的数据(这时l1里面的[1,2]也会变成[1,200])
简单的说就是复制一个外壳,里面的数据用的都是一样的,但是改变元素的时候,可变类型的元素不共用,可变类型的数据共用一套
深copy:
import copy
l1=[1,2,3,[1,2]]
l3=copy.deepcopy(l1)
# 此时两个列表的id也不同
深copy的时候,不可变的元素共用,但是修改的时候创建一个新的数据,指向新的数据(这和浅copy是一样的),对于可变的元素(例如l1里面的[1,2]),是复制一个新的外壳(id不一样),里面的元素还是共用,但是修改的时候,是会指向新的数据,对原来的列表没有影响(解决了可变类型的元素共用的问题,修改元素时互不影响)
数据类型装换和方法
整型
在python中,age=10,相当于age=Int(10),int()函数就是将一个对象转换成整型的数据,需要注意的是,转换字符串的时候,只能将纯数字的字符串转换成整型(浮点数也一样),否则会报错
十进制转换成二进制bin()函数
十进制转换成八进制oct()函数
十进制转换成十六进制hex()函数
二进制转换成十进制 int('10010',2)第二个数字2是说明前面的数字是二进制的意思,八进制就写8,十六进制就写16
内置方法:基本上没啥方法,多在算数运算和比较运算中使用
浮点型
float()将一个对象转换成浮点数类型,
虚数
complex(实部,虚部)
可以了解一下位运算相关知识
字符串类型
str()将任意类型的数据转换成字符串
s1='hello world'
# 按照索引取值和切片
s1[3] # 得到l
s1[1:7:2] # 从索引1开始到索引8结束,每隔两个字符(步长)取一个值得到el o
s1[-1:-3] # 得到lr
s1[::-1] # 倒着取全部的字符串
## 需要注意的是 字符串不能通过索引进行改值,因为是不可变的数据类型
# 统计长度
len(s1)
# in和not in
判断字符是否存在在字符串中,返回true或false
'l'in s1 # true
# strip() 移除字符串两侧的符号,只去除两边,不去除中间的
s2='nihao/.//*'
s3=s2.strip('') # 括号里面是想要去掉的符号,剩下nihao/.//</span>
s4=s2.strip('*/.') # 去掉两边的多种符号,只剩下nihao
lstrip() # 只去除左边的(left)
rstrip() # 只去除右边的(right)
## 应用在输入的时候对字符串进行处理(去掉两边的空格)
# split和rsplit切分方法,按照某种分隔符进行拆分,得到的是一个列表(默认分隔符是空格)
s1.split(' ') # 按照空格进行拆分,得到['hello','world']
s1.split(' ',1) # 设置分隔次数(就是从第一个空格开始分隔,分成两个元素的列表)
s1.rsplit(' ',1) # 从右向左开始切分
# s1.upper() 英文字母全部大写 HELLO WORLD
s1.isupper() # 判断是否全是大写
s1.lower() 英文字母全部小写 hello world
s1.islower() # 判断是否全是小写
s1.isdigit() # 判断是否全是数字
s1.title() 对单词的首字母的大写 Hello World
s1.startswith('h') 判断是不是以h开头的字符串
s1.endswith('d') 判断是不是以d结尾的字符串
# join()将列表拼接成字符串
l1=['ni','hao','ya']
'!'.join(l1) # 用!l1的三个元素连起来——》'ni!hao!ya'
# replace()替换方法
s1.replace("l",'L',1) # 将第一个l替换成大写的L,如果不写数字默认替换掉所有
# 了解内容
find()和index()
s1.find('ll')
s1.index('ll')
# 两者都是返回查找的子字符串的第一个字符的索引,不同之处在于find如果找不到返回的是-1,index如果找不到直接报错,所以使用find要好一点
# s1.count('l') # 返回l在字符串中出现了多少次
# center()rjust()ljust()zfill()
'nihao'.center(20,'') # 创造一个20字符长度的字符串,nihao居中显示,其他的位置用填充
'nihao'.rjust(20,'') # 创造一个20字符长度的字符串,nihao右对齐显示,其他的位置用填充
'nihao'.ljust(20,'') # 创造一个20字符长度的字符串,nihao左对齐显示,其他的位置用填充
'nihao'.zfill(20) # 创造一个20字符长度的字符串,nihao右对齐显示,其他的位置用0填充,z是zero的意思
# s1.expandtabs(10) # 当s1中有制表符时,指定制表符的长度,这里指定的是10个字符长度
# s1.capitalize() # Hello world整个字符串的第一个首字母大写
s1.swapcase() # 将字符串中的大写字符变成小写,小写字符变成大写
# is系列,判断字符串中的字符的种类,返回true和false
.islower() # 全是小写
.isupper() # 全是大写
.istitle() # 单词的首字母是大写
.isalnum() # 全是字母或者数字
.isalpha() # 全是字母
.isdecimal() # 全是数字
.isspace() # 全是空格
.isidentifier() # 判断标识符是不是合法的,如果是关键字的话返回true
# .numberic()和.digit()和.isdecimal()的区别
.isnumberic() # 能够判断是不是阿拉伯数字、罗马数字、中文数字
.isdigit() # 只能判断是不是阿拉伯数字(Unicode和bytes类型的数字)
.isdecimal() # 智能判断是不是unicode显示的数字(python3中默认是unicode)
列表
list()方法,将一个可迭代对象变成列表,元素就是可迭代对象的每一个元素,列表式有序的
列表可以通过切片和索引进行取值
l1=[111,'nihao',3.3]
# 查
l1[0] # 结果是111
l1[0:3:2] # 结果是切片相当于一种copy,是一种浅copy,不改变本身的值,只是复制一份
# 改
l1[0] =222 # 索引存在的话可以直接改值,不存在的话直接报错[222,'nihao',3.3]
# 增
l1.append('qidian') # 在列表后面追加值[222,'nihao',3.3,'qidian']
l1.insert(0,'ni') # 在索引为0的位置直接添加值['ni',222,'nihao',3.3,'qidian']
l1.extend('abc') # 迭代着追加在列表的后面['ni',222,'nihao',3.3,'qidian','a','b','c']
# 删
del l1[0] # 通用的删除方法,单纯的删除,但是没有返回值,无法赋值
l1.pop(2) # 根据索引删,不指定索引(括号里面不填值),默认删除最后一个,有返回值,返回删除的那个值
l1.romove('nihao') # 按照对象删,制定删除的对应元素,返回值是none
# in和 not in 也适用于列表
# 一些需要掌握的内置方法
l1.count() # 查找元素出现的次数
l1.index() # 查找元素的索引
l1.clear() # 清空元素,将列表变为空列表
l1.reverse() # 将元素的顺序颠倒
l1.sort() # 默认是从小到大排序(升序),传入参数reverse=true(默认是false),变成元素从大到小排序(降序)
## 在使用sort方法时,列表内元素必须是同种类型才可以,字符串的排序是按照ASCII码表的顺序来比较的,在进行字符串的比较的时候,是按照相对应的位置的字符来比较的,同理列表的比较也一样
不建议在循环中修改列表等可变数据类型,因为这样会改变列表的索引
队列和堆栈
队列:一种数据结构,特点是FIFO(first in first out)像是管道
堆栈:特点是LIFO(last in first out)像是水桶
元组
元组是一种不可变得数据类型,相当于一个不可变的列表,但是元组内的元素不能重复,元组的作用就是按照索引存放多个值,只用于读不能修改
对于元组中存放的可变的数据类型(比如说列表),是可以进行修改的,但是列表的内存地址是没有改变的
元祖的函数是tuple()
元祖的表示是(1,2,3,4,5,6),需要注意的是,只存放一个数据的时候,表示为(1,)(1)表示的是整数1
# 无法进行修改,所以增删改都不可以使用,只能使用索引查看,可以切片查看,可以使用in和 not in判断,方法只能使用index和count,与上面的原理一样,这里就不说了
字典是键值对组成的,键(key)和值(value)是一一对应的
key必须是不可变的数据类型,并且不可重复,value可以是任何类型
表示{'name':'david','age':18}
创建字典的函数方式:dict()
# 空字典{}
# 字典的创建
d=dict(x=1,y=2,c=3)
l=[[1,'a'],[2,'b'],[3,'c']]
d1=dict(l) # 直接得到字典{1:'a',2:'b',3:'c'}
key1=[1,2,3]
none
{}.fromkeys(key1,none) # 得到字典{1:none,2:none,3:none},原理将前面的可迭代对象的每一个元素都当做key,值是同一个,都是none,这种方式常常用于快速初始化一个字典,值的部分通常不使用可变的数据类型,一般是none,或者是可变的数据类型
# 改/增
d1={1:'a',2:'b',3:'c'}
d1[1] # 查看值,如果键值对不存在会直接报错
d1.get(1,'当key不存在的时候get方法的返回值') # 是为了弥补使用索引进行查询的时候,如果字典中没有对应的键会直接报错,但是get方法会返回none
d1[1]='asd' # 键存在的话就是直接修改值
d1[4]='d' # 如果key不存在的话就直接增加键值对
len(d1) # 计算长度
# 成员运算in 和 not in判断的是key
# 删除
del d1[1] # 直接删除键值对
d1.pop(1) # 默认删除最后一个,或者按照键删除,返回删除的key对应的值
d1.popitem() # 随机删除,返回删除键值对组成的元组
# 其他的一些方法,下面是在python2中得到的结果,在python3中进行了优化,将每个得到的结果换成了迭代器,为了节省内存空间
d1.keys() # 得到key组成的列表
d1.values() # 得到value组成的列表
d1.items() # 得到键值对组成的元组形成的列表
d1.clear() # 全删除,清空
d1.update(d2) # 在d1中有的键值对,还继续保留,d1中没有d2中有的键值对,将其增加到d1中
d1.setdefault(1,'abc') # 如果键值在原字典中存在,就不会对原字典进行修改
d1.setdefault(5,'e') # 如果键不存在,就将键和默认值形成键值对添加到字典中
集合
在{}内用逗号分隔开多个元素,元素满足以下条件:
集合内元素必须是不可变类型
集合内元素无序
集合内元素没有重复
{}是空集合,集合的函数是set()
集合有两个用处,一个是关系运算,一个是去重
# 类型转换
s=set('abcde') # {'a','b','c','d','e'}要注意的是,集合里面放的是不可变的数据类型
# 集合的关系运算与相关的内置方法
s1={1,2,3,4,5}
s2={2,3,4,5,6}
# 取交集,两个集合共有的元素
s1&s2 # {2,3,4,5}
s1.intersection(s2)
# 取并集,两个集合相加去重
s1|s2 # {1,2,3,4,5,6}
s1.union(s2)
# 取s1独有的元素(差集)
s1-s2 # {1}
s1.difference(s2)
# 对称差集,就是两个元组所独有的元素组成的集合
s1^s2 # {1,6}
s1.symmetric_difference(s2)
# 父子集,包含的关系若s1的元素包含s2里面的元素,就称s1是父集合,s2是子集合(两个集合相等就互为父子)
s1>s2 # 用大于小于表示,返回true或者false,这里的s1和s2不存在父子关系,返回false
s1.issuperset(s2)
s1.subset(s2)
# 集合的去重(有局限性)
局限1.只能针对不可变得数据类型进行去重
局限2.无法保证原来的顺序
# 集合可以计算长度len()方法
集合可以进行成员运算in和not in
集合可以用for方法进行循环
s1.remove(1) # 可以删除元素,但是删除不存在的元素会报错所以有了discard方法
s1.discard(9) # 同样可以删除,但是删除不存在的元素的时候什么都不会做,相当于没进行操作
s1.update(s3) # 将新集合加到原来的集合中在将重复的去掉(相当于取并集)
update方法可以和交集并集等方法运算的函数结合使用,下面举个例子就明白了
s1.deiierence_update(s2) # 就是先去差集然后在进行update
s1.clear() # 将集合进行清空
s1.pop() # 随机删除
s1.add(8) # 增加元素
s1.isdisjoint() # 如果两个集合完全独立,没有共同部分,返回true
数据类型总结
按照存值个数区分 | |
---|---|
只能存一个值,称为标量/原子类型 | 数字、字符串 |
可以存多个量,称为容器类型 | 列表、元组、字典 |
按访问方式区分 | |
---|---|
直接访问,只能通过变量值访问某个值 | 数字 |
顺序访问:可以通过索引访问,也叫序列类型 | 字符串、列表、元组 |
key访问:又被称为映射类型 | 字典 |
按照可变不可变区分 | |
---|---|
可变类型 | 列表、字典 |
不可变类型 | 数字、字符串、元组 |
案例:打印三位回文数(第一位和第三位相同的数字)
i=100
while i<1000:
if i//100 == i%10:
print(i)
i+=1
案例:打印乘法表
i=1
while i < 10:
j=1
while j <i+1:
print('%d*%d=%d' %(i,j,i*j),end=' ')
j+=1
print()
i+=1
案例:累加求和
# 打印1到100的和
i=0
j=0
while j<=100:
j+=1
i=i+j
print(i)