目录
一、Python简介
1、Python发展史
Python是一种广泛使用的解释星型号、高级编程、通用型编程语言,由“龟叔”吉多·范罗苏姆创造,第一版发布于1991年
Python的设计哲学强调代码的可读性和简介的语法(尤其是使用空格缩进划分代码块,而非使用大括号或者关键词),相比于C++或Java,Python让开发这能够用更少的代码表达想法,不管是小型还是大型程序,该语言都试图让程序的结构清晰明了
2、Python理解
Python是一门解释型语言
解释型语言 | 编译型语言 | |
概念 | 程序不需要编译,程序在运行时才翻译成机器语言,每执行一次都要翻译一次,因此效率比较低;每个语句都是执行的时候才翻译,因此效率比较低,依赖解释器,跨平台性好 | 程序在执行之前需要一个专门的编译过程,把程序编译成为机器语言的文件,运行时不需要重新编译,直接使用编译的结果就行了,程序执行效率高,依赖编译器,跨平台性差些 |
特点 | 不需要事先编译,其直接将源代码解释成机器代码并立即执行,所以只要某一平台提供了相应的解释器即可运行该程序 | 只需编译一次,以后运行时不需要编译,所以编译型语言执行效率高 |
语言 | python、JavaScript等 | C、C++等 |
3、Python的优缺点
(1)优点
简单易上手、代码风格及简、免费开源、完善的基础代码库、众多的第三方库、代码可读性高、程序可移植
(2)缺点
相比于编译型语言,速度会慢点、代码不能加密
二、Python开发环境搭建
1、环境搭建
windows环境下python+集成开发环境之PyCharm安装
Python开发环境搭建可参考:自动化测试-selenium_自动版本测试-CSDN博客
2、尝试写一个基础程序
(1)调整配置
第一次打开PyCharm时,我们选择不设置其他配置,如图:
接着根据自己的喜好选择背景颜色(这里也可以后续设置)
接着提示是否要安装其他插件,这个暂时不需要,我们先跳过即可,到下一步我们没有激活码,就先点击试用,后续如果觉得有需要再自行激活,调整到这里,一些默认的设置就设置完成了,我们开始新建一个项目
(2)新建项目
选择文件->新建项目,修改项目存储位置,点击创建即可
(3)新建py文件
右键点击项目名->新建->python文件,输入文件名回车即可,在该文件中输入内容
(4)运行程序
右键点击空白区域,选择运行程序,可以看到下方区域输出程序的运行结果,显示结果无误
print("Hello world")
备注:
只要是编写完Python打码,并形成任意一个.py结尾的文件,都能够正常运行,所以使用哪种方式,取决于开发的舒适度
三、Python基础数据类型
1、数字类型
(1)数字类型支持的数值
- 整型:可正可负,不带小数点,在Python3中整型没有大小限制,也可以存储长整型
- 浮点型:可正可负,带小数点,可以使用科学计数法表示【1.1e2=110】
- 复数:复数由实数部分和虚数部分构成,可以用 a + bj 或者 complex(a,b) 表示,复数的实部 a 和虚部 b 都是浮点型,应用较少
(2)数字类型的特点
数字类型是不可变的,如果改变数字类型的值,将重新分配内存空间
注意:这里的不可变,指的是数字类型的值,一旦确认,其地址对应的值不可变,如果变量的值改变了,则会将变量指向新的地址
(3)示例说明
这里使用【id()】函数,可以查看值改变前后变量的当前指向地址
# 变量a 和 b 值相同
由下图可以看出,变量 a 和 b 指向了同一个地址
a = 1
b = 1
print(id(a))
print(id(b))
# 变量a的值发生变化
由下图可以看出,变量 a 的值发生变化后,指向了不同的地址
a = 1
print(id(a))
a = 2
print(id(a))
2、各进制转换
(1)各进制理解
# 二进制
它的基数为2,进位规则是“逢二进一”
如上图所示,将余数倒过来写一起,就是该数字的二进制表示方式,即10101
# 八进制
它的基数为8,进位规则是“逢八进一”
# 十进制
日常中使用的最多的就是10进制
# 十六进制
它的基数为16,进位规则是“逢十六进一”,跟其他几个进制不同的地方是该进制大于十的时候,会使用A-F进行表示
(2)python进制分辨
在Python中,如果没有显式指定进制,那么所有的数字默认是按十进制算,使用如下方式显示指定进制:
二进制 | 八进制 | 十进制 | 十六进制 |
前面加0b或0B | 前面加0o或0O | 默认值 | 前面加0x或0X |
(3)进制转换
原进制(下)/待转换进制(右) | 二进制 | 八进制 | 十进制 | 十六进制 |
二进制 | 无 | oct(0b10) | int('0b10',2) | hex(0b10) |
八进制 | bin(0o10) | 无 | int('0o10',8) | hex(0o10) |
十进制 | bin(10) | oct(10) | 无 | hex(10) |
十六进制 | bin(0x10) | oct(0x10) | int('0x10',16) | 无 |
十进制快速转换为其他进制的转换规则:
用十进制数,每次除以对应的数,记下余数,直到最终结果为0,之后将余数倒过来写,如果是16进制,余数大于10,转换为字母即可
3、布尔类型/bool函数
(1)理解
对与错、是与非、正与反,都是传统意义上的布尔类型,在Python中,统一使用True和False来表示布尔类型
布尔类型一般用于表示条件是否成立,成立用True,不成立用False
布尔类型是数字类型的一个子集
(2)bool函数使用
bool函数可以用来测试一个表达式的布尔值结果
print(bool(0)) # False
print(bool(-1)) # True
print(bool(0b1010)) # True
print(bool('表达式')) # True
print(bool('')) # False
4、字符串及其编码
(1)字符串定义
字符串是由数字、字母、符号组成的一串字符,它是编程语言中表示文本的数据类型
在Python中,使用双引号、单引号、三引号括起来的一系列字符就是字符串,无论是使用单引号还是双引号,都必须成对出现
计算机中储存的信息都是用二进制数表示的;而我们在屏幕上看到的英文、汉字等字符是二进制数转换之后的结果通俗的说,按照何种规则将字符存储在计算机中,如'a' 用什么表示,称为 " 编码" ;反之,将存储在计算机中的二进制数解析显示出来,称为 " 解码 "
(2)字符常见的字符集
# ASCII
计算机一开始是外国人发明的,他们日常使用就是一些日常符号加上大小写的字母、数字,所以在字符集的设计上,也只兼容这样的一些字符
# GBXXXX
ASCII码只能存英文,所以GB2312应运而生,它所收录的汉字已经覆盖中国大陆99.75%的使用率,对于人名、古汉语等方面出现的罕用字,GB2312不能处理,所以有了GBK编码
# Unicode
主要的编码方式有:UTF-32、UTF-16、UTF-8(最常用)
Python3版本中,所有的字符串都是使用Unicode编码的字符串序列
字符串的特性是不可变的,如果改变了字符串的值,相当于重新分配了空间
5、引号/转义字符
(1)引号使用
一般情况下,如果我们要表示字符串,会使用单引号或者双引号,但是当字符串带有单引号或双引号时,就需要使用转义字符了,或者可以切换使用单双引号
- 当字符串中有单引号时,使用双引号括起来
- 当字符串中有双引号时,使用单引号括起来
在Python中,若输入字符串过多,需要换行,解决办法:
- 使用成对出现的三单引号括起来
- 使用转义字符【\n】
print('你说:"我很好,谢谢你"\n'
'wsddfghds')
print('''qqq
qertyui
13456
''')
(2)常见转义字符
在Python中,如果某些字符本身有特殊含义或者无法使用ASCII码进行表示的时候,需要对其进行转义操作,一般用单一反斜杠【\】进行转义
常见的转义字符:
转义字符 | 含义 |
\a | 发出系统铃声 |
\' | 单引号 |
\n | 换行 |
\\ | 反斜杠 |
\" | 双引号 |
\b | 退格 |
\t | 纵向制表符 |
\v | 横向制表符 |
\r | 回车 |
\f | 换页 |
6、字符串常见的操作
(1)获取字符串的某一部分
操作 | 输出 |
"my name is cendy-LL"[0] | m |
"my name is cendy-LL"[3] | n |
"my name is cendy-LL"[-1] | L |
"my name is cendy-LL"[-2] | L |
"my name is cendy-LL"[0:2] | my |
"my name is cendy-LL"[0:-1] | my name is cendy-L |
"my name is cendy-LL"[0:18] | my name is cendy-L |
"my name is cendy-LL"[0:19] | my name is cendy-LL |
"my name is cendy-LL"[0:] | my name is cendy-LL |
"my name is cendy-LL"[:7] | my name |
(2)字符串的格式化
在字符串中,可以将一个值插入到有格式化符号的地方
print("my name is %s and my age is %d" %("cendy-LL",25))
常用的格式化符号:
符号 | 作用 |
%c | 格式化字符及其ASCII码 |
%s | 格式化字符串 |
%d | 格式化整数 |
%f | 格式化浮点数,可指定小数点后的精度 |
四、Python运算符
1、算术运算符
(1)作用
用于支持日常一些普通的算术运算
(2)常用算术运算符
算术运算符 | 作用 |
+ | 加 |
- | 减 |
* | 乘 |
/ | 除 |
% | 求余 |
// | 取整除 |
** | n次幂 |
2、比较运算符
(1)作用
用于支持日常一些常用的比较运算
(2)常用比较运算符
比较运算符 | 作用 |
> | 大于 |
< | 小于 |
== | 等于 |
!= | 不等于 |
>= | 大于等于 |
<= | 小于等于 |
<> | 不等于,作用同【!=】,在3.7版本已废弃 |
3、赋值运算符
(1)作用
用于设置值
(2)常用赋值运算符
赋值运算符 | 作用 |
= | 直接赋值 |
+= | 将加后的结果赋值自身 |
-= | 将减后的结果赋值自身 |
*= | 将乘后的结果赋值自身 |
/= | 将除后的结果赋值自身 |
//= | 将取整除后的结果赋值自身 |
%= | 将取余后的结果赋值自身 |
**= | 将幂运算后的结果赋值自身 |
4、位运算符
(1)位运算符介绍
程序中的所有数在计算机内存中都是以二进制的形式存储的,位运算就是直接对整数在内存中的二进制位进行操作
(2)常用的位运算符
位运算符 | 运算符名称 | 作用 |
& | 按位与运算符 | 参与运算的两个值,如果两个相应位都为1,则该位的结果为,否则为0 |
| | 按位或运算符 | 只要对应的两个二进位有一个为1时,结果位就为1 |
<< | 左移动运算符 | 运算数的各二进位全部左移若干位,由“<<”右边的数指定移动的位数,高位丢弃,低位补0 |
>> | 右移动运算符 | 把“>>”左边的运算数的各二进位全部右移若干位,“>>”右边的数指定移动的位数 |
~ | 按位取反运算符 | 对数据的每个二进制位取反,即把1变为0,把0变为1 |
^ | 按位异或运算符 | 当两对应的二进位相异时,结果为1 |
5、逻辑运算符
(1)常用逻辑运算符
逻辑运算符 | 作用 |
and | 表示与关系,前后均成立为真,对于 【x and y】,如果 x 为 False,【x and y】返回 x ,否则它返回 y 的计算值 |
or | 表示或关系,前后只要一个为真即为真,对于【x or y】,如果 x 为 非,它返回 x 的值 ,否则它返回 y 的计算值 |
not | 表示非关系,后面条件不成立时为真,对于【not x】,如果 x 为 True,返回 False,如果 x 为 False,它返回 True |
(2)示例
# and 表示与关系 对于【x and y】,x结果为True时,则返回y的值;x结果为False时,直接返回x的值
print(True and False) # False
a = 3
b = 4
print(a > 2 and b < 4) # False
print('12' and 123) # 123
print('' and 123) # (空的)
print('----------------------------------')
# or 表示或关系 对于【x or y】,如果 x 为 非,它返回 x 的值 ,否则它返回 y 的计算值
a = 1
b = 2
print(a == 2 or b == 2) # True
print('' or '123') # 123
print(1 or 3) # 1
print('----------------------------------')
# not 表示非关系,后面条件不成立时为真,对于【not x】,如果 x 为 True,返回 False,如果 x 为 False,它返回 True
a = 2
b = 0
print(not a == 2) # False
print(not a == 1) # True
print(not a) # False
print(not b) # True
6、成员运算符/身份运算符
(1)常见成员运算符
运算符种类 | 运算符 | 作用 |
成员运算符 | in | 表示在xxx里面 |
not in | 表示不在xxx里面 | |
身份运算符 | is | 是xxx |
is not | 不是xxx |
(2)示例
# 成员运算符 in / not in
a = '123'
b = '12'
print(b in a) # True
a = '123'
b = '12'
print(b not in a) # False
# 身份运算符 is / is not
a = '123'
b = '123'
print(b is a) # True
a = '123'
b = '123'
print(b is not a) # False
注意:
【is 与 == 区别】
is 用于判断两个变量引用对象是否为同一个;== 用于判断引用变量的值是否相等
a = [1, 2, 3]
b = a[:]
print(a) # [1, 2, 3]
print(b) # [1, 2, 3]
print(b is a) # False
print(b == a) # True
7、运算符的优先级
(1)运算符优先级
运算符优先级对照下面的表格,数字越大,优先级越高!
运算符说明 | Python运算符 | 优先级 |
索引运算符 | x[index] 或 a[index:index2[:index3]] | 18、19 |
属性访问 | x.attrbute | 17 |
乘方 | ** | 16 |
按位取反 | ~ | 15 |
符号运算符 | +(正号)或 - (负号) | 14 |
乘、除 | * / // % | 13 |
加、减 | + - | 12 |
位移 | >> << | 11 |
按位与 | & | 10 |
按位异或 | ^ | 9 |
按位或 | | | 8 |
比较运算符 | == != > >= < <= | 7 |
is 运算符 | is 、 is not | 6 |
in 运算符 | in 、 not in | 5 |
逻辑非 | not | 4 |
逻辑与 | and | 3 |
逻辑或 | or | 2 |
注意:优先级相同的运算符,计算时从左往右计算
print(4 * 4 // 3) # 输出结果:5
(2)应用规范
- 不要把一个表达式写的过于复杂,如果一个表达式过于复杂,则会把它分成几步来完成
- 不要过多依赖运算符的优先级来控制表达式的执行顺序,这样会降低程序可读性,应尽量使用【()】来控制表达式的执行顺序
print(-4 ** 2 / 2 + 1 // 3) # 输出结果:-8.0
五、Python之流程控制语句
1、条件语句
(1)条件语句理解
条件语句是用来判断给定的条件是否满足(表达式值是否为0),并根据判断的结果(真或假)决定执行的语句,选择结构就是用条件语句来实现的
简单理解:如果明天下雨,我就不去打球了
if 明天下雨 then
do 不去打球
(2)语法格式
if 条件:
结果
elif 条件:
结果
else:
结果
(3)示例
使用if else比较两个数的大小,并输出大的数字
a = 1
b = 2
if a > b:
print(a)
else:
print(b)
(4)条件语句与三元表达式
# 三元表达式格式
条件为真时的结果 if 条件判断 else 条件为假的结果
即:x if x > y else y
# 示例
使用三元表达式输出两个数中较大者
a = 1
b = 2
print(a if a > b else b)
2、for循环语句
(1)基本语法
for variabe in sequence:
do something
else:
do something
(2)示例
示例1:统计1加到100的值
result = 0
for i in range(101):
result += i
else:
print("i的值大于100了,现在i的值是:", i + 1)
print(result)
示例2:计算1到100内所有偶数之和
result = 0
for i in range(101):
if i % 2 == 0:
result += i
print("1到100内所有偶数之和为:", result)
3、while循环语句
(1)语法
while循环语句同for循环类似,都是在需要循环执行某些语句时使用,语法格式如下:
while condition:
do something
while循环与else,表示当while后面的条件不成立时,执行else里的代码块,语法格式如下:
while condition:
do something
else:
do smething
(2)示例
示例1:使用while循环语句统计从1加到100的值
i = 0
result = 0
while i <= 100:
result += i
i += 1
print("1到100内所有偶数之和为:", result)
示例2:使用while...else循环语句统计从1加到100的值,然后打印出【计算完成!】
i = 0
result = 0
while i <= 100:
result += i
i += 1
else:
print("计算完成!")
print("不满足条件后,当下i的值是:", i)
print("1到100内所有偶数之和为:", result)
(3)死循环
当while后面的条件恒成立时,while循环进入无限循环,也称为死循环
while True:
print("Hello World")
4、嵌套语句
在Python中,与其他大多数语言一样,允许循环之间嵌套
(1)for循环嵌套基本语法
for variable in sequence:
for variable in sequence:
do something
do something
(2)for循环嵌套示例
for i in range(2):
print("这是第%d次循环" % (i + 1))
for j in range(2):
print("j")
示例2:使用for循环打印99乘法表,形成如下格式,各列使用制表符【\t】分隔
for i in range(1, 10):
for j in range(1, i + 1):
print(i, "*", j, "=", i * j, "\t", end='')
print("")
(3)while循环嵌套基本语法
while condition:
while condition:
statements
statements
(4)while循环嵌套示例
i = 0
while i < 2:
print("这是第%d次循环" % (i + 1))
i += 1
j = 0
while j < 2:
print("j")
j += 1
5、循环退出语句及作用
(1)跳过整个循环
在循环中,当碰到某些特定的条件时要跳过整个循环,可以使用【break】关键字退出循环
例如:下面的语句表示当变量 i 等于5的时候,退出整个循环
for i in range(10):
if i == 5:
break
else:
print(i)
(2)跳过当次循环
在循环中,当碰到某个特定条件时,想跳过当次循环,可以使用【continue】关键字
例如:下面的语句表示当变量 i 等于5的时候,跳出当次循环
for i in range(10):
if i == 5:
continue
else:
print(i)
六、Python之数据结构
1、列表(list)
(1)理解
列表是一种数据项构成的有限序列,即按照一定的线性顺序排列而成的数据项的集合,在这种数据结构上进行的基本操作包括对元素的查找、插入和删除
(2)列表结构
在Python中,使用方括号 [] 来表示列表
[item,item,item,item,item,item]
列表存储如下图所示:
(3)列表常见操作
操作 | 说明 |
list.append(obj) | 在列表后面新增元素 |
del list[i] | 删除元素 |
len(list) | 求列表长度 |
list[i] | 读取第 i - 1 个元素 (列表下标从0开始) |
list[-i] | 读取倒数第 i 个元素(这里的 i 就是取倒数第几个) |
list[i,j] | 从第 i 个元素开始截取 |
list.index(objc) | 从列表中找出某个值第一次出现的地方(即该值第一次出现的下标) |
list.insert(i,obj) | 在第 i 个元素的位置插入元素(注意正向下标从0开始) |
list.pop(i) | 移除第 i 个元素,并返回其值 |
L = [1, 2, 3, 4, 5, 6, 7, 8]
L.append(5)
print(L) # [1, 2, 3, 4, 5, 6, 7, 8, 5]
del L[1]
print(L) # [1, 3, 4, 5, 6, 7, 8, 5]
print(len(L)) # 8
print(L[2]) # 4
print(L[-3]) # 7
print(L.index(8)) # 6
L.insert(3, 55)
print(L) # [1, 3, 4, 55, 5, 6, 7, 8, 5]
pop = L.pop(5)
print(pop) # 6
print(L) # [1, 3, 4, 55, 5, 7, 8, 5]
(4)列表的特性
# 成员有序
放进去的顺序和取出来的顺序是一致的
L = [1, 2, 3, 4, 5]
print(L)
# 成员可重复出现
列表成员可以重复
M = [1, 1, 1, 1, 1]
print(M)
2、集合(set)
(1)创建集合
在Python中,一般使用{} 或者 set() 函数创建集合,如下:
{item,item,item......}
注意:
当我们要创建一个空集合时,只能用 set() 进行创建,因为 {} 表示的是空的字典
(2)集合常见操作
操作 | 说明 |
set.add(item) | 往集合里添加一个元素 |
set.update(item) | 往集合里添加元素,item 是可迭代对象,如:列表、元祖、字典等 |
set.remove(item) | 将元素 item 从集合 set 中移除,如果元素不存在,则会发生错误 |
set.discard(item) | 将元素 item 从集合 set 中移除,如果元素不存在,不会发生错误 |
set.pop() | 随机取出并删除一个元素 |
set.len() | 计算集合个数 |
set.clear() | 清空集合 |
union() | 取两个集合的并集 |
(3)集合的特性
# 成员无序
my_set = {'小红', '小橙', '小绿'}
print(my_set)
# 成员不可重复出现
my_set = {'小红', '小红', '小红'}
print(my_set)
3、元组(tuple)
(1)理解
Python 中的元组与列表非常相似,不同之处在于元组的元素不能修改,整个元组也不能变动
(2)创建元组
元组使用 () 来创建,创建元组时,只要在括号中添加相应的元素,并使用逗号分隔即可
tup = (1, 2, 3)
注意:
当我们创建一个只有一个元素的元组的时候,在元素后面要加一个逗号,如:tup = (1,)
(3)元组常见的操作
操作 | 说明 |
新增元素 | 不允许 |
修改元素 | 不允许 |
删除某个元素 | 不允许 |
tup[i] | 获取第 i 个元素 |
tup[-i] | 获取倒数第 i 个元素 |
tup[i:j] | 获取从第 i 个元素起到第 j 个元素(左闭右开,不包括下标为j的元素) |
(4)示例
tup = (1, 2, 3, ["111", "222", "333"])
tup[-1][0] = "444"
print(tup)
修改元组里列表的值,修改成功,list本身是可变对象,list 的地址里存的都是实际内容的指针,此时元组的内容指向 list 地址,无论 list 的内容如何变更,list的地址也不会改变,所以并不违背 tup 里存储的元素不能改变的原则
元组的元素不能改变,但是如果元组里存在一个列表,那么列表里的值可以修改
4、字典(dict)
(1)理解
在Python中,字典类型可存储任意类型对象,它用于存放具有映射关系的数据,其映射关系通过 key:value 的形式体现
(2)创建字典
创建字典时,每个键值对以 key:value 的形式存在,通过大括号 {} 包裹,每个键值对通过逗号分隔,形式如下:
{key1: value1, key2: value2}
(3)字典常用的操作
操作 | 说明 |
update({1:2}) | 新增元素 |
dict['key'] | 通过 key 后去对应的值,如果没有对应的 key,会报错 |
dict['key']=123 | 修改 key 对应的值 |
del dict['key'] | 删除一个 key 及其对应的 value |
del dict | 清空整个字典 |
len(dict) | 获取字典元素个数 |
(4)字典的特性
- 在字典中,key 不能重复,如果放入相同的 key ,后者的值会覆盖前者
- 在字典中,key 必须是不可变的
# key 是不能重复的,如果放相同的key,后者的值会覆盖前者
d = {1: 1, 2: 2}
d.update({1: 123})
print(d)
# 字典中的key,必须不可变
y = {[1, 2, 3]: 123}
print(y)
5、range类型
(1)理解
range() 函数返回的是一个可迭代对象(类型是对象),而不是列表类型,所以打印的时候不会打印列表
如果想把 range对象变成列表,可以使用 list() 函数对 range 进行处理
print(list(range()))
(2)语法
range(stop)
range(start=, stop=, step=)
- start:计数从 start 开始;默认是从0开始,例如:range(5) 等价于 range(0,5)
- stop:计数到 stop 结束,但不包括 stop,例如:range(0, 5) 返回值是 [0, 1, 2, 3, 4]
- step:步长,默认为1,例如:range(0, 5) 等价于 range(0, 5, 1)
(3)示例
print(list(range(6))) # 输出结果:[0, 1, 2, 3, 4, 5]
print(list(range(1, 6))) # 输出结果:[ 1, 2, 3, 4, 5]
print(list(range(1, 6, 2))) # 输出结果:[1, 3, 5]
print(list(range(-11, -6))) # 输出结果:[-11, -10, -9, -8, -7]
print(list(range(1, -6, -1))) # 输出结果:[1, 0, -1, -2, -3, -4, -5]
6、可变与不可变对象
(1)理解
可变与不可变是相对于内存里的那块地方是否可以改变,通俗点讲,就是内存中对应的地址在值发生变动时会不会改变,如果地址不变,为可变对象;地址变动时,则为不可变对象
(2)示例
a = 1
print(id(a))
a = a + 1
print(id(a))
从上图可以看出,在 a 的值发生变动(a = a + 1)的时候,a 对应的地址也发生了改变,其本质原因在于数字类型不可变,如果值要变动,会在内存里重新开辟一个空间用于存储相应的值
(3)对象分类
- 可变类型:列表、字典
- 不可变类型:数字、字符串、元组
七、Python特性之切片
1、切片
(1)切片缘由
对于一个列表 L = [1, 2, 3, 4, 5, 6, 7, 8, 9],如果我们想获取前三个元素,有两个方法:
方法1:
L = [1, 2, 3, 4, 5, 6, 7, 8, 9]
print(L[0], L[1], L[2])
方法2:
L = [1, 2, 3, 4, 5, 6, 7, 8, 9]
i = 0
while i < 3:
print(L[i])
i += 1
上面这两种方法,似乎都能实现需求,但是如果需求发生变化,比如取第2到5个或者2到最后一个,就比较麻烦了~
(2)切片操作
对于列表和元组的操作,我们可以使用 list[i:j] 来访问,这种操作就是切片,对于一个列表 L = [1, 2, 3, 4, 5, 6, 7, 8, 9] ,我们使用切片来获取特定元素
操作 | 说明 |
L[0:3] | 获取第1个到3个元素 |
L[1:5] | 获取第2个到5个元素 |
L[-5:-1] | 获取倒数第5个到倒数第2个元素 |
L[3:] | 获取第4个到最后一个元素 |
L[:5:2] | 前5个数,每隔2个取一个元素 |
L[::2] | 所有数,每隔2个取一个元素 |
L = [1, 2, 3, 4, 5, 6, 7, 8, 9]
print(L[0:3]) # [1, 2, 3]
print(L[1:5]) # [2, 3, 4, 5]
print(L[-5:-1]) # [5, 6, 7, 8]
print(L[3:]) # [4, 5, 6, 7, 8, 9]
print(L[:5:2]) # [1, 3, 5]
print(L[::2]) # [1, 3, 5, 7, 9]
(3)切片类型
- 可切片类型:字符串、列表、元组
- 不可切片类型:集合、字典
2、列表生成式
(1)生成式语法
写法1:[expr for iter_var in iterable]
写法2:[expr for iter_var in iterable if cond_expr]
- 写法1:首先迭代 iterable 里所有内容,每一次迭代,都把 iterable 里相应内容放到 iter_var 中,再在表达式中应用该 iter_var 的内容,最后用表达式的计算值生成一个列表
- 写法2:加入了判断语句,只有满足条件的内容才把 iterable 里相应内容放到 iter_var 中,再在表达式中应用该 iter_var 的内容,最后用表达式的计算值生成一个列表
(2)生成式使用
示例1:生成一个10个元素的列表,每个分别对应1-10的两倍
my_list = [x * 2 for x in range(1, 11)]
print(my_list)
示例2:生成一个100以内所有偶数的列表
my_list = [x for x in range(1, 101) if x % 2 == 0]
print(my_list)
示例3:生成一个 [1,0],[1,1],[1,2],[1,3],[1,4],[1,5],[2,0],[2,1],[2,2],[2,3],[2,4],[2,5]的列表
my_list = [[x, y] for x in range(1, 3) for y in range(0, 6)]
print(my_list)
3、迭代
在Python中,只要是可迭代的对象,无论有没有下标,都可以进行迭代,比如:list、set、tuple、str、dict
判断一个对象是否可迭代:
from collections.abc import Iterable
print(isinstance('aaa',Iterable))
可迭代对象里的数据成对出现,一次性遍历两个对象,如下:
for x, y in [(1, 2), (4, 5)]:
print("x+y=", x + y)
4、生成器
(1)生成器缘由
通过列表生成式,可以直接创建一个列表,但会受到内存的限制,列表容量是有限的,当列表元素很大的时候,会很浪费内存空间,所以可以通过生成器 Generator 生成
(2)生成器返回值
生成器是一种一边循环一边计算的机制,相比于列表生产式,只需将最外层的 [] 换成 () 即可,变换后,返回的类型也随着改变
【列表生成式】返回的是 list
print(type([x * 2 for x in range(1, 11)]))
【生成器】返回的是 generator 类型
print(type((x * 2 for x in range(1, 11))))
(3)生成器使用
# 直接使用 next(generator)
c = (x * 2 for x in range(1, 3))
print(next(c))
print(next(c))
print(next(c))
print(next(c))
缺点:有多少个可获取的元素不可预估,当超出范围之后,会报 StopIteration
# 使用循环
c=(x * 2 for x in range(1,3))
for i in c:
print(i)
该方式更加灵活,不用担心 StopIteration
八、函数
1、Python函数及其调用
(1)函数定义
- 函数是组织好的,可重复使用的,用来实现单一或者相关联功能的代码段
- 函数能提高应用的模块性和代码的重复利用率
(2)函数调用
- 函数调用写法:函数名(参数)
注意:参数一定要符合函数定义时的入参,对于Python中提供的函数,可以使用 help(函数名) 来查看相关调用时的相关说明,如 help(hex)
在Python中,意味着函数名是指向一个函数对象的引用,我们可以把函数名赋给一个变量,相当于给这个函数起了一个别名,示例:
p = print
p(123)
2、Python中的自定义函数
(1)定义函数的结构
def 函数名(入参):
函数逻辑
return
(2)自定义求圆形面积的函数
PI = 3.14
def circle_area(r):
return PI * r ** 2
print(circle_area(2))
(3)自定义空函数
def empty_fun():
pass
print(empty_fun())
3、函数返回多个值
法1:直接在函数里把多个返回值按一定顺序放到list、tuple里
def my_fun():
return [1, 2, 3]
print(my_fun())
print(type(my_fun()))
法2:多个返回值以 key-value 的形式放在字典(dict)里
def my_fun():
return {"x": 1, "y": 2, "z": 3}
print(my_fun())
法3:在 return 的时候返回多个逗号分隔的值,在返回的时候,也可以直接用多个变量接收
def my_fun():
return 33, 44, 55
x, y, z = my_fun()
print(x, y, z)
注意点:返回多个参数时,如果想一次性用多个变量接收,那么有多少个返回值就得有多少个变量接收,返回多个值,本质上返回的是一个元组
def my_fun():
return 1, 2, 3
print(my_fun())
print(type(my_fun()))
4、函数的递归
(1)递归定义
一种计算过程,如果其中每一步都要用到前一步或前几步的结果,称为递归,用递归过程定义的函数,称为递归函数
注:当自己写递归函数时,首要步骤是要先写函数的最终结束条件
(2)示例:阶乘运算
使用递归,进行阶乘运算 【5!】
def factorial(n):
if n == 1:
return 1
else:
return n * factorial(n - 1)
print(factorial(5))
(3)示例:斐波那契数列第n项的值
斐波那契数列,指的是这样一个数列:1、1、2、3、5、8、13、21、34......在数学上,斐波那契数列以如下被以递推的方法定义:F(1)=1,F(2)=1,F(n)=F(n-1)+F(n-2)(n>=3,n=N*)
def feb(n):
if n < 3:
return 1
else:
return feb(n - 1) + feb(n - 2)
print(feb(6))
(4)最大递归层级
Python中有最大的递归层级,可使用如下代码获取最大层级
import sys
print(sys.getrecursionlimit())
九、参数与变量
1、形参与实参以及位置参数
(1)形参理解
即形式参数,函数定义时指定的可以接受的参数即为形参,比如定义函数时的max(a, b)函数中的 a 和 b 就是形参
(2)实参理解
即实际参数,调用函数时传递给函数参数的实际值即为实参,比如调用上面函数用 max(1, 9),函数中的 1 和 9 就是实参
def my_max(a, b):
return a if a > b else b
print(my_max(2, 7))
(3)位置参数理解
我们在定义函数 max(a,b) 后,在调用时,我们无需指定参数名,只需 max(1,9),这个时候实参入参的位置进行匹配,也就是在函数中,a=1,b=9
如果我们不想基于位置顺序,也可以直接指定对应的参数名,比如 max(b=8, a=5),这个时候调用后,不会按入参顺序赋值,而是直接按指定的参数名赋值
print(my_max(b=8, a=5))
2、默认参数
编写一个计算 x 的 n 次幂的函数,要求[x、n]可以作为参数传入
def power(x, n):
return x ** n
print(power(2, 2))
上面的函数虽然解决了问题,但是不够完美,假设在大部分的调用里,基本都只是求 x 的 2次幂,但这个时候在调用的时候依旧每次都需要传 n ,这显得有点多余
在函数入参处可以使用等号赋值默认参数,如下:
def power(x, n=2):
return x ** n
print(power(2))
注意:必需要的参数在前,默认参数在后,否则会报错
若有多个默认参数的时候,可以显示指定传入某个参数的值,在调用函数时,入参使用【参数名=参数值】的形式即可,如下:
def test(a=1, b=2, c=3):
print("a=%d b=%d c=%d" % (a, b, c))
test(c=2)
如果默认参数是一个列表,如下:
def test(L=[]):
L.append("END")
print(L)
test([1, 1, 1])
test([2, 2, 2])
test()
test()
函数在定义的时候,默认参数的值已经确定,换句话说,L指向的地址已确定,之后如果还是对其内容进行更改的话,默认参数的值也随之改变了
注意:默认参数必须指向不可变对象
3、可变参数
(1)含义
可变参数就是调用函数时,传递参数的个数是可变的
若不使用可变参数,则【list、dict、set等】可以实现传入不确定个数,但调用方不清楚入参是哪种类型,此时调用方还得看函数的具体实现知道入参是可迭代类型
def sum(numbers):
total = 0
for i in numbers:
total += i
return total
print(sum([1, 2, 3]))
(2)基本格式
在定义函数的时候,入参前加【*】号,表示可变参数,如下:
def my_fun(*numbers):
print(type(numbers))
total = 0
for i in numbers:
total += i
return total
print(my_fun(1, 2, 3))
可变参数,其实是将入参封装成元组
4、命名关键字参数
(1)定义
限制调用者不能按位置传递,需要放在形参的后面,并在前面使用星号【*】(独占一个参数位)与普通形参分隔
(2)缘由
为了限制后面几个参数只能按关键字传递,这往往是因为后面几个形参名具有十分明显的含义,显示写出有利于可读性;或者后面几个形参随着版本更迭很可能会发生变化,强制关键字形式有利于保证跨版本兼容性
与位置参数相对的另一种方式,是每次调用的时候,都必须指定参数的名字,也就是命名关键字
(3)用法
命名关键字使用【*】做分隔,【*】之前的参数基于位置参数;【*】后面的参数,在调用的时候必须指定其参数
def person(name, age, *, pet):
print(name, age, pet)
person("cendy", 29, pet="tomcat")
一旦使用命名关键字之后,如果调用时没指定参数名,会报相应的错误
def person(name, age, *, pet):
print(name, age, pet)
person("cendy", 29, "tomcat")
【*】后面的参数,同样也可以使用默认参数进行设置
def person(name, age, *, pet="cat"):
print(name, age, pet)
person("cendy", 29)
注意:如果函数定义中已经有了一个可变参数,后面跟着的命名关键字参数就不再需要一个特殊分隔符
5、关键字参数
(1)关键字参数理解
关键字参数允许传入0个或者任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个 dict
def person(name, age, **kw):
print('名字:',name,'年龄:',age,'其他情况:', kw)
person("cendy", 29, city="杭州", pet="喵喵")
也可以使用下面的方式传参
other_info表示把other_info这个dict的所有 key-value 用关键字参数传入到函数的 **kw 参数,kw 参数将获得一个 dict
注意:kw 获得的 dict 是 other_info 的一份拷贝,对 kw 的改动不会影响到函数外的 other_info
def person(name, age, **kw):
print('名字:', name, '年龄:', age, '其他情况:', kw)
other_info = {"pet": "喵喵","sex":"男"}
person("cendy", 29, city="杭州", **other_info)
(2)混合使用参数
各类型的参数可以在定义函数时混合使用
注意点:参数定义的顺序必须是:必选参数、默认参数、可变参数、命名关键字参数和关键字参数