【Python】基础语法

【Python】基础语法,第1张

文章目录
  • 1 出使Python国
    • 1.1 Python自述
    • 1.2 搭建Python开发环境
    • 1.3 Python中的输出函数
    • 1.4 转义字符与原字符
  • 2 七十二变
    • 2.1 二进制与字符编码
    • 2.2 Python中的标识符与保留字
    • 2.3 Python中的变量与数据类型
    • 2.4 Python中的注释
  • 3 算你赢
    • 3.1 Python的输入函数input()
    • 3.2 Python中的运算符
    • 3.3 运算符的优先级
  • 4 往哪走呢?
    • 4.1 程序的组织结构
    • 4.2 顺序结构
    • 4.3 对象的布尔值
    • 4.4 分支结构(选择结构)
    • 4.5 pass空语句
  • 5 转圈圈
    • 5.1 range()函数的使用
    • 5.2 循环结构
    • 5.3 流程控制语句
    • 5.4 嵌套循环
  • 6 一字排开
    • 6.1 列表的创建与删除
    • 6.2 列表的查询 *** 作
    • 6.3 列表元素的增、删、改 *** 作
    • 6.4 列表元素的排序
  • 7 夫妻站
    • 7.1 什么是字典
    • 7.2 字典的原理
    • 7.3 字典的创建与删除
    • 7.4 字典的常用 *** 作
    • 7.5 字典生成式
  • 8 是排还是散
    • 8.1 元组
    • 8.2 集合
    • 8.3 列表、字典、元组、集合总结
  • 9 一串连一串
    • 9.1 字符串的驻留机制
    • 9.2 字符串的常用 *** 作
    • 9.3 字符串的比较 *** 作
    • 9.4 字符串的切片 *** 作
    • 9.5 格式化字符串
    • 9.6 字符串的编码转换
  • 10 水晶球不调用不动
    • 10.1 函数的创建和调用
    • 10.2 函数的参数传递
    • 10.3 函数的返回值
    • 10.4 函数的参数定义
    • 10.5 变量的作用域
    • 10.6 递归函数
  • 11 全民来找茬
    • 11.1 Bug的分类
    • 11.3 Python的异常处理机制

1 出使Python国 1.1 Python自述
  • 我为什么值得你拥有?

  • 我为什么能成为网红?
    我对大数据缝隙、人工智能中至关重要的机器学习、深度学习都提供了大力的支持。
    我背后有最最庞大的“代码库”
    人们习惯称我为“胶水语言”

  • 我能帮你做些啥?
    抢火车票、数据分析少踩坑、开发网站、开发游戏

  • 你需要根据我的发展方向进行自身定位

掌握技术职业方向
Web全栈开发方向前端开发
数据库管理
后台框架技术
Web全栈开发工程师
数据科学方向数据库管理
数据分析
数据可视化
能够制作数据看板
实现数据指标监控
数据产品经理
量化交易
初级BI商业分析师等
人工智能方向-机器学习掌握机器学习常用算法思想
能够利用Python建立机器学习模型,对一些应用场景进行智能化
数据分析工程师
机器学习算法工程师
搜索算法工程师
推荐算法工程师
人工智能方向-深度学习掌握深度学习常用框架
可自行搭建图像相关算法,实现图像分类,人脸识别
可自行搭建NLP常见算法,实现文本分类、问答系统等
掌握GAN网络相关算法,实现图像自动上色,图像美化等
人工智能工程师
  • Python简介
    我是一个“90后”,我孕育在1989年的圣诞节期间,我的程序员爸爸荷兰人吉多-范罗苏姆,为了打发无趣的圣诞节创造了我,我在1991年正式公布,我的程序员爸爸给我起了个非常吓人的名字叫Python(大蟒蛇),取自于英国20世纪70年代首播的电视喜剧《蒙提-派森的飞行马戏团》(Monty Python’s Flying Circus)。
    现在我已经更新到3.0版本了,被大家叫做Python3000,熟悉我的朋友会称我为Py3k,我的爸爸在2020年1月1日,官宣停止了Python2的更新。
  • Python特点
    跨平台的计算机程序设计语言:把你的想法告诉我,我再以计算机认识的方式告诉它,我是你们之间的交流工具。
    解释型语言:我在开发过程中没有编译这个环节,这点和Java不同。
    交互式语言:可以在我的提示符>>后直接执行代码
    面向对象的语言:在我的世界一切皆对象
1.2 搭建Python开发环境

安装参考:https://blog.csdn.net/weixin_49026134/article/details/120575480
Python安装成功后可以看到4个程序:

1.3 Python中的输出函数

print() 函数功能:向目的地输出内容

  • 输出内容:数字、字符串、含有运算符的表达式
  • 输出形式:换行、不换行
  • 目的地:IDLE、控制台、文件
# 输出内容:数字、字符串、含有运算符的表达式
print(3.1415)
print('HelloWorld')
print(1+2)

# 输出方式:不换行(输出内容在一行当中)
print('HelloWorld', '123')

# 将数据输出在文件中,注意:1.所制定的盘符存在;2.使用file=fp
fp = open('D:/Print.txt', 'a+')     # a+表示以读写的方式打开文件。如果文件不存在就创建,文件存在则在原有内容上进行追加。
print('Hello World', file=fp)
fp.close()
1.4 转义字符与原字符
  • 常用的转义字符
转义字符的分类要表示的字符转义字符备注
无法直接表示的字符换行\nnewline光标移动到下一行的开头
回车\rreturn光标移动到本行的开头
水平制表符\ttab键,光标移动到下一组4个空格的开始处
退格\b键盘上的backspace键,回退一个字符
在字符串中有特殊用途的字符反斜杠\
单引号\'
双引号\"
  • 原字符
    不希望字符串中的转义字符起作用,就使用原字符,在字符串之前加上r或R。
    # 转义字符
    print('Hello\nWorld')
    print('Hello\rWorld')
    # 注意:什么时候重开一个制表位,取决于\t之前是否占满制表位,占满则重开,不占满就不重新开
    print('Hello\tWorld')
    print('Helloooo\tWorld')
    print('Hello\bWorld')
    
    print('http:\\www.baidu.com')
    print('老师说:\"大家好\"')
    
    # 原字符
    print(r'Hello\nWorld')
    

制表位图解:什么时候重开一个制表位,取决于\t之前是否占满制表位,占满则重开,不占满就不重新开

2 七十二变 2.1 二进制与字符编码
  • 计算机换算单位
    8 bit (位) = 1 byte (字节)
    1024 byte = 1 KB (千字节)
    1024 KB = 1MB (兆字节)
    1024 MB = 1 GB (吉字节)
    1024 GB = 1 TB (太字节)

  • 字符编码

# chr(i):返回整数i所对应的Unicode字符。
print(chr(0b100111001011000))   # 0b 表示二进制
print(chr(0o47130)) # 0o表示八进制
print(chr(20056))  # 十进制
print(chr(0x4e58))  # 0x 表示十六进制

# ord(): 是chr()函数(对于8位的ASCII字符串)或unichr()函数(对于Unicode对象)的配对函数,以一个字符(长度为1的字符串)作为参数,返回对应的ASCII/Unicode数值。
print(ord('乘'))
2.2 Python中的标识符与保留字
  • 保留字
    查看python的保留字:
    import keyword
    print(keyword.kwlist)
    
  • 标识符
    定义:变量、函数、类、模块和其他对象起的名字就叫标识符。
    命名规则:
    1. 可以使用字母、数字、下划线
    2. 不能以数字开头
    3. 不能是保留字
    4. 严格区分大小写
2.3 Python中的变量与数据类型
  • 变量组成
    标识(id):标识对象所存储的内存地址,使用内置函数id(obj)来获取
    类型(type):表示对象的数据类型,使用内置函数type(obj)来获取
    值(value):表示对象所存储的具体数据,使用print(obj)可以将值进行打印输出
    name = 'Bob'
    print('标识:', id(name))
    print('类型:', type(name))
    print('值:', name)
    
  • 常用的数据类型
类型简写取值
整数类型int98
浮点数类型float3.14159
布尔类型boolTrue/False
字符串类型str‘人生苦短,我用Python’

1 整数类型
英文为integer,简写为int,可以表示正数,负数和零。
整数的不同进制表示方式:十进制(默认的进制),二进制(以0b开头),八进制(以0o开头),十六进制 (以0x开头)

print('十进制:', 119)
print('二进制:', 0b100111010)
print('八进制:', 0o1771)
print('十六进制:', 0x1f)

2 浮点数类型
浮点数由整数部分和小数部分组成。
浮点数存储不精确:使用浮点数进行计算时,可能会出现小数位数不确定的情况,如:print(1.1+2.2) # 输出:3.3000000000000003
解决方案:导入模块decimal

a = 3.14159
print(a, type(a))
print(1.1+2.1)
print(1.1+2.2)
from decimal import Decimal
print(Decimal('1.1')+Decimal('2.2'))


3 布尔类型
用来表示真或假的值。
布尔值可以转换为整数:True>>1, False>>0

b1, b2 = True, False
print(b1, type(b1), b2, type(b2))
# 布尔值可以转成整数计算
print(b1 + 1)   # True表示1
print(b2 + 1)   # False表示0

4 字符串类型
字符串又被称为不可变的字符序列。
可以用单引号‘ ’,双引号“ ”,三引号‘’‘ ‘’’或““” “””来定义。
单引号和双引号定义的字符串必须在一行。
三引号定义的字符串可以分布在连续的行。

str1 = '人生苦短,我用Python'
str2 = "人生苦短,我用Python"
str3 = '''人生苦短,
    我用Python'''
str4 = """人生苦短,
    我用Python"""
print(str1, type(str1))
print(str2, type(str2))
print(str3, type(str3))
print(str4, type(str4))
  • 数据类型转换
    将不同数据类型的数据拼接在一起。
    name = '张三'
    age = 20
    # print('我叫' + name + ',今年' + age + '岁')   # 当将str类型与int类型进行连接时会报错。解决方案:类型转换!
    print('我叫' + name + ',今年' + str(age) + '岁')
    
函数名作用注意事项举例
str()将其他数据类型转成字符串也可以用引号转换str(123)
‘123’
int()将其他数据类型转成整数1. 文字类和小数类字符串,无法转成整数
2. 浮点数转成整数,抹零取整
int(‘123’)
int(9.8)
float()将其他数据类型转成浮点数1. 文字类无法转成浮点数
2. 整数转成浮点数,末尾为.0
float(‘9.8’)
float(9)
a, b, c, d, e = 10, 200.20, False, 'Hello', '2.22'
print(type(a), type(b), type(c), type(d), type(e))
# 转成str
sa, sb, sc, sd, se = str(a), str(b), str(c), str(d), str(e)
print(sa, sb, sc, sd, se, type(sa), type(sb), type(sc), type(sd), type(se))
# 转成int: 文字类和小数类字符串,无法转成整数
ia, ib, ic = int(a), int(b), int(c)
print(ia, ib, ic, type(ia), type(ib), type(ic))
# 转成float: 文字类无法转成浮点数
fa, fb, fc, fe = float(a), float(b), float(c), float(e)
print(fa, fb, fc, fe, type(fa), type(fb), type(fc), type(fe))
2.4 Python中的注释

类型:

  1. 单行注释:以#开头,知道换行结束
  2. 多行注释:并没有单独的多行注释标记,将一对三引号之间的代码称为多行注释
  3. 中文编码声明注释:在文件开头加上中文声明注释,用以指定源码文件的编码格式# coding:gbk, # -*- coding:utf-8 -*-
3 算你赢 3.1 Python的输入函数input()
  • 介绍
    作用:接受来自用户的输入
    返回值类型:输入值得类型为str
    值的存储:使用=对输入的值进行存储
  • 基本使用
    # 从键盘中输入两个整数,并计算它们的和
    a = input('请输入一个加数')
    b = input('请输入另一个加数')
    print(type(a)), print(type(b))	#注意:返回值类型为str
    print(a + b)    #字符串类型+号表示拼接
    print(int(a) + int(b))
    
    执行结果如下:
3.2 Python中的运算符
  • 算术运算符
    标准算术运算符:加(+),减(-),乘(*),除(/), 整除(//)
    取余运算符:%
    幂运算符:**

    print(1+1)    # 加法
    print(1-1)    # 减法
    print(2*2)    # 乘法
    print(9/4)   # 除法
    print(2**3)   # 幂运算
    print(9//4)  # 取整
    print(-9//-4)
    print(9//-4)  # 取整:一正一负向下取整
    print(-9//4)
    print(9%4)    # 取余
    print(-9%-4)
    print(9%-4)   # 取余:一正一负要公式:余数=被除数-除数*商 9-(-4)*(-3)=-3
    print(-9%4)   # -9-4*(-3)=3
    
  • 赋值运算符
    标识:=
    执行顺序:从右到左
    支持链式赋值:a=b=c=10
    支持参数赋值:+=, -=, *=, /=, //=, %=
    支持系列解包赋值:a,b,c=10,20,30

    # 解包赋值应用:交换两个变量的值,不需要中间变量!
    a,b=10,20
    print('交换之前:', a, b)
    a,b=b,a
    print('交换之后:', a, b)
    
  • 比较运算符
    对变量或表达式的结果进行大小、真假等比较。
    大于(>),小于(<),大于等于(>=),小于等于(<=),不等于(!=)
    对象value的比较:==
    对象id的不计较:is, is not

    a = 10
    b = 10
    print('a==b?', a==b)
    print('a is b?', a is b)
    l1 = [1, 2, 3]
    l2 = [1, 2, 3]
    print('l1==l2?', l1==l2)
    print('l1 is l2?', l1 is l2)
    

    运行结果如下:

  • 布尔运算符
    对于布尔值之间的运算。
    and:当两个运算数为True时,运算结果才为True
    or:只要有一个运算数为True,运算结果就位True
    not:若运算数为True(False),则运算结果为False(True)
    in, not in

  • 位运算符
    将数据转成二进制进行计算。
    位与&:对应数位都是1,结果数位才是1,否则为0
    位或|:对应数位都是0,结果数为才是0,否则为1
    左移位运算符<<:高位溢出舍弃,低位补0
    右移位运算符>>:低位溢出舍弃,高位补0

    print('4&8:', 4&8)
    print('4|8:', 4|8)
    print('4<<1:', 4<<1)
    print('4<<2:', 4<<2)
    print('4>>1:', 4>>1)
    print('4>>2:', 4>>2)
    

    运行结果如下:

3.3 运算符的优先级

有括号先算括号里面的。

4 往哪走呢? 4.1 程序的组织结构

任何简单或复杂的算法都可以由顺序结构、选择结构和循环结构这三种基本结构组合而成。

4.2 顺序结构

程序从上到下顺序地执行代码,中间没有任何的判断和跳转,直到程序结束。

4.3 对象的布尔值

Python一切皆对象,所有对象都有一个布尔值。
获取对象的布尔值:使用内置函数bool()。
以下对象的布尔值为False,其它对象的布尔值均为True:

  • False
  • 数值0
  • None
  • 空字符串
  • 空列表
  • 空元组
  • 空字典
  • 空集合
print(bool(False))
print(bool(0))
print(bool(0.0))
print(bool(None))
# 空字符串
print(bool(''))
print(bool(""))
# 空列表
print(bool([]))
print(bool(list()))
# 空元组
print(bool(()))
print(bool(tuple()))
# 空字典
print(bool({}))
print(bool(dict()))
# 空集合
print(bool(set()))
4.4 分支结构(选择结构)

程序根据判断条件的布尔值选择性地执行 部分代码。明确地让计算机知道在什么条件下,该去做什么。

  • 单分支if结构
    中文语义:如果…就…
    语法结构:
    if 条件表达式:
    	条件执行体
    
  • 双分支if…else结构
    中文语义:如果…就…否则就…
    语法结构:
    if 条件表达式:
    	条件执行体1
    else:
    	条件执行体2
    
  • 多分支if…elif…else结构
    中文语义:成绩是在90分以上吗?成绩是在80-90分之间吗?成绩是在60-80之间吗?成绩是在60分以下吗?
    语法结构:
    if 条件表达式1:
    	条件执行体1
    elif 条件表达式2:
    	条件执行体2
    elif 条件表达式n:
    	条件执行体n
    [else:]
    	条件执行体n+1
    
  • if语句的嵌套
    语法结构:
    if 条件表达式1:
    	if 内层条件表达式1
    		内层条件执行体1
    	else:
    		内层条件执行体2
    else:
    	条件执行体
    
  • 条件表达式
    条件表达式是if…else的简写
    语法结构:x if 判断条件 else y
    运算规则:如果判断条件的布尔值为True,条件表达式的返回值为x,否则条件表达的返回值为y(条件判断为True,执行前边的代码;条件判断为False,执行后边的代码)
    # 从键盘录入2个整数,比较两个整数的大小
    a = int(input('Please enter the 1st integer:'))
    b = int(input('Please enter the 2rd integer:'))
    # if a>=b:
    #     print(a, '>=', b)
    # else:
    #     print(a, '<', b)
    print(str(a)+'>='+str(b) if a>=b else str(a)+'<'+str(b))
    
4.5 pass空语句

语句什么都不做,只是一个占位符,用在语法上需要语句的地方。
什么时候使用:先搭建语法结构,还没想好代码怎么写的时候。
哪些语句一起使用:

  • if语句的条件执行体
  • for-in语句的循环体
  • 定义函数时的函数体
5 转圈圈 5.1 range()函数的使用

内置函数range():用于生成一个整数序列,起始值默认为0,步长默认为1。
创建range对象的三种方式:

返回值是一个迭代器对象。
range类型的优点:不管range对象表示的整数序列有点多长,所有range对象占用的内存空间都是相同的,因为仅仅需要存储start, stop和step,只有当用到range对象时,才会去计算序列中的相关元素。
in和not in判断整数序列中是否存在(不存在)指定的整数。

r1 = range(10)  # 默认start=0, step=1
print(r1)   # 输出:range(10)
print(list(r1)) # 用于查看range对象中的整数序列

r2 = range(1, 10)   # 指定起始值,默认step=1
print(list(r2))

r3 = range(1, 10, 2)   # 指定起始值和步长
print(list(r3))

print(10 in r1)
print(0 not in r2)
5.2 循环结构

反复做同一件事情的情况,成为循环。

  • while循环
    用于次数不固定的循环。
    语法结构:
    while 条件表达式:
    	条件执行体(循环体)
    
    选择结构的if与循环结构while的区别:
    1. if是判断一次,条件为True执行一次
    2. while是判断N+1次,条件为True执行N次
    	a = 1
    	if a<10:
    	    print(a)
    	    a+=1
    	
    	b = 1
    	while b<10:
    	    print(b)
    	    b+=1
    
    四步循环法:初始化变量 >> 条件判断 >> 条件执行体(循环体) >> 改变变量
    	# 计算1-100之间的偶数和
    	'''初始化变量'''
    	a = 0
    	sum = 0
    	'''条件判断'''
    	while a <= 100:
    	    '''条件执行体(循环体)'''
    	    # if a%2 == 0:
    	    if not (a % 2):
    	        sum += a
    	    '''改变变量'''
    	    a += 1
    	print('1-100之间的偶数和为:', sum)
    	
    	# 计算1-100之间的奇数和
    	a = 0
    	sum = 0
    	while a <= 100:
    	    if a % 2:
    	        sum += a
    	    a += 1
    	print('1-100的奇数和为:', sum)
    
  • for-in循环
    in表达从(字符串、序列等)中依次取值,又称遍历。
    for-in遍历的对象必须是可迭代对象(字符串、序列等),用于遍历可迭代对象。
    语法结构:
    for 自定义的变量 in 可迭代对象:
    	循环体
    
    循环体内不需要访问自定义变量,可以将自定义变量替代为下划线。
    # for-in遍历的对象必须是可迭代对象——字符串
    for item in 'Python':
        print(item)
    
    # for-in遍历的对象必须是可迭代对象——序列,range()生成一个整数序列
    for i in range(1, 10):
        print(i)
    
    # 如果在循环体中不需要使用到自定义变量,可将自定义变量写为"_"
    for _ in range(3):
        print('人生苦短,我用Python')
    
    练习题:
    # 输出100-999之间的每个水仙花数(153=3*3*3+5*5*5+1*1*1)
    for i in range(100, 1000):
        sigle = i % 10    # 个位数=数除以10取余
        ten = i // 10 % 10    # 十位数=数除以10取整后再除以10取余
        hundred = i //100   # 百位数=数除以100取整
        if i == sigle**3 + ten**3 + hundred**3:
            print(i)
    
5.3 流程控制语句
  • break语句
    用于退出当前循环结构,通常与分支结构if一起使用。
    # 从键盘上输入密码,最多录入3次,如果正确就结束
    # for-in循环
    for i in range(3):
        pwd = input('Please enter your password')
        if pwd == '666666':
            print('Password correct!')
            break
        else:
            print('Password incorrect!')
    
    # while循环        
    i = 0
    while i < 3:
        pwd = input('Please enter your password')
        if pwd == '666666':
            print('Password correct!')
            break
        else:
            print('Password incorrect!')
        i += 1
    
  • continue语句
    用于结束当前循环,进入下一次循环,通常与分支结构中的if一起使用。
    # 输出1-50之间所有是5的倍数
    for i in range(1, 51):
        # if i % 5 != 0:
        if i % 5:
            continue
        else:
            print(i)
    
  • else语句
    与else语句搭配使用的三种情况:
    # 从键盘上输入密码,最多录入3次,如果正确就结束
    # for-in循环
    for i in range(3):
        pwd = input('Please enter your password')
        if pwd == '666666':
            print('Password correct!')
            break
        else:
            print('Password incorrect!')
    else:
        print('Oops, wrong password three times.')
    
    # while循环
    i = 0
    while i < 3:
        pwd = input('Please enter your password')
        if pwd == '666666':
            print('Password correct!')
            break
        else:
            print('Password incorrect!')
        i += 1
    else:
        print('Oops, wrong password three times.')
    
5.4 嵌套循环

循环结构中嵌套了另外的完整的循环结构,其中内层循环做为外层循环的循环体执行。

# 输出九九乘法表
for i in range(1, 10):
    for j in range(1, 1+i):
        print(i, '*', j, '=', i*j, end='\t')	# 不换行输出
    print()		#换行输出

  • 二重循环中的break和continue
    只控制本层循环。
# 流程控制语句break和continue在二重循环中的使用
for i in range(5):   # 代表外层循环要执行5次
    for j in range(1, 11):
        if j%2 == 0:
            break
        print(j)
        
for i in range(5):   # 代表外层循环要执行5次
    for j in range(1, 11):
        if j%2 == 0:
            continue
        print(j, end='\t')
    print()
6 一字排开
  • 列表的特点
    列表元素按顺序有序排序;
    索引映射唯一个数据;
    列表可以存储重复数据;
    任意数据类型混存;
    根据需要动态分配和回收内存;
6.1 列表的创建与删除
  • 列表的创建
    使用中括号
    调用内置函数list()
    列表生成式:生成列表的公式
    # 1. 中括号
    lst1 = ['Hello', 'World', 100]
    
    # 2. list()
    lst2 = list(['Hello', 'World', 100])
    
    # 3. 列表生成式
    lst = [i for i in range(1, 10)]
    print(lst)		# [1, 2, 3, 4, 5, 6, 7, 8, 9]
    
    lst2 = [i*i for i in range(1, 10)]
    print(lst2)		# [1, 4, 9, 16, 25, 36, 49, 64, 81]
    
    # 列表中的元素的值为2,4,6,8,10
    lst3  = [i*2 for i in range(1, 6)]
    print(lst3)		# [2, 4, 6, 8, 10]
    
  • 列表的删除
    del 列表名
6.2 列表的查询 *** 作
  • 查询元素索引——index()
    如果列表中存在N个相同的元素,只返回相同元素中的第一个元素的索引;
    如果查询的元素在列表中不存在,则会抛出ValueError;
    可以在指定的start和stop之间进行查找;

    lst = ['Hello', 'World', 100, 'Hello']
    print(lst.index('Hello'))	# 0
    print(lst.index('hello'))	# ValueError
    print(lst.index('Hello', 1, 4))	# 3
    
  • 获取单个元素——[索引]
    正向索引从0到N-1;
    逆向索引从-N到-1;
    指定索引不存在,抛出indexError;

    lst = ['Hello', 'World', 100, 'Hello']
    print(lst[2])   # 100
    print(lst[-2])  # 100
    print(lst[100]) # IndexError
    
  • 获取多个元素——切片
    语法格式:列表名[start: stop: step]

    lst = [10, 20, 30, 40, 50, 60, 70, 80]
    print('原列表:', id(lst))
    lst2 = lst[1:6]
    print('切的列表:', id(lst2))    # 原列表片段的拷贝
    print(lst[1:6:2])   # [20, 40, 60]
    print(lst[:6:2])    # [10. 30. 50]
    print(lst[1::2])    # [20, 40, 60, 80]
    print(lst[::-1])    # [80, 70, 60, 50, 40, 30, 20, 10]
    print(lst[7::-1])   # [80, 70, 60, 50, 40, 30, 20, 10]
    print(lst[6:0:-2])   # [70, 50, 30]
    print(lst[6::-2])   # [70, 50, 30, 10]
    
  • 判断指定元素在列表中是否存在
    元素 in 列表名 元素 not in 列表名

  • 列表元素的遍历

    for 迭代变量 in 列表名:
    	 *** 作
    
    lst = [10, 20, 'python']
    for item in lst:
        print(item)
    
6.3 列表元素的增、删、改 *** 作
  • 列表元素的增加 *** 作
    lst = [10, 'python']
    print('原始列表:', lst, id(lst))
    lst.append(100)
    print('append之后:', lst, id(lst))
    lst2 = ['Hello', 'World']
    lst.append(lst2)
    print('append添加lst2:', lst)     # [10, 'python', 100, ['Hello', 'World']]
    lst.extend(lst2)
    print('extend添加lst2:', lst)     # [10, 'python', 100, ['Hello', 'World'], 'Hello', 'World']
    lst.insert(1, 90)
    print('insert *** 作之后:', lst)      # [10, 90, 'python', 100, ['Hello', 'World'], 'Hello', 'World']
    lst3 = [True, False, 'hi']
    lst[1:] = lst3
    print(lst)      # [10, True, False, 'hi']
    lst[1:3] = lst3
    print(lst)		# [10, True, False, 'hi', 'hi']
    
  • 列表元素的删除 *** 作
    lst = [10, 20, 30, 40, 50, 60, 30]
    lst.remove(30)
    print(lst)  # [10, 20, 40, 50, 60, 30]
    lst.pop(1)
    print(lst)  # [10, 40, 50, 60, 30]
    lst.pop()
    print(lst)  # [10, 40, 50, 60]
    # 切片 *** 作删除至少一个元素,将产生一个新的列表对象, 原列表不变
    new_lst = lst[1:3]
    print('原列表:', lst)
    print('切片后的新列表:', new_lst)  # [40, 50]
    # 不产生新的列表对象,而是删除原列表中的内容
    lst[1:3] = []
    print(lst)  # 10, 60]
    lst.clear()
    print(lst)  # []
    del lst
    print(lst)  # name 'lst' is not defined
    
  • 列表元素的修改 *** 作
    为指定索引的元素赋予一个新值;
    为指定的切片赋予一个新值;
    lst = [10, 20, 30, 40]
    lst[1] = 100
    print(lst)  # [10, 100, 30, 40]
    lst[1:3]=[300, 400, 500, 600]
    print(lst)   # [10, 300, 400, 500, 600, 40]
    
6.4 列表元素的排序

常见的两种方式:
(1)调用sort()方法,列表中的所有元素按照从小到大的顺序进行排序,可以指定reverse=True,进行降序排序。对原列表进行 *** 作。
(2)调用内置函数sorted(),可以指定reverse=True,进行降序排序。产生新列表,原列表不发生改变。

lst = [10, 40, 100, 93, 66]
print('排序前的列表', lst, id(lst))
lst.sort()  # sort()默认升序排序,不产生新列表
print('排序后的列表', lst, id(lst))
lst.sort(reverse=True)  # reverse=True 降序排序
print(lst)

new_lst = sorted(lst)   # sorted()默认升序排序,产生新列表,原列表不变
print('原列表:', lst)
print('新列表:', new_lst)
desc_lst = sorted(lst, reverse=True)	# reverse=True 降序排序
print('降序排序:', desc_lst)
7 夫妻站 7.1 什么是字典

Python内置的数据结构之一,与列表一样是一个可变序列(可以增删改)。
以键值对的方式存储数据,字典是一个无序的序列。

  • 字典的特点
    字典中的所有元素都是一个key-value对,key不允许重复,value可以重复;
    字典中的元素是无序的;
    字典中的key必须是不可变对象;
    字典也可以根据需要动态地伸缩;
    字典会浪费较大的内存,是一种空间换时间的数据结构;
7.2 字典的原理
  • 字典示意图
    往字典当中进行存储数据的时候,需要经过一个叫hash()函数的工序,把键放到hash()函数中计算存储位置。所以位置不是根据放的先后顺序得来的,而是经过hash()函数计算得来的。所以键必须是不可变序列(字符串,整数序列)。
  • 字典的实现原理
    与查字典类似,查字典是先根据部首或拼音查找对应的页码,Python中的字典是根据key查找value所在的位置。
7.3 字典的创建与删除
  • 字典的创建
    使用花括号:scores = {'张三':100, '李四': 60}
    使用内置函数dict():scores = dict(张三=100, 李四=60)
    使用字典生成式

  • 字典的删除
    del scores

7.4 字典的常用 *** 作
  • 字典中元素的获取
    [key]:scores['张三']
    get(key)方法:scores.get('张三')
    []取值和get()取值区别:

    1. []如果字典不存在指定的key,抛出keyError异常;
    2. get()方法取值,如果字典不存在指定的key,并不会抛出keyError而是返回None,可以通过参数设置默认的value,以便指定的key不存在时返回。
    scores = {'张三':100, '李四': 60}
    print(scores['张三'])         # 100
    print(scores.get('张三'))     # 100
    # print(scores['王五'])       # KeyError
    print(scores.get('王五'))     # None
    print(scores.get('王五', 99)) # 99, 99是王五不存在时提供的默认值
    print(scores.get('李四', 99)) # 60
    
  • key的判断
    in:指定的key在字典中存在返回True
    not in:指定的key在字典中不存在返回True

  • 字典元素的删除
    删除指定元素:del scores['张三']scores.pop['张三']
    清空字典所有元素:scores.clear()

  • 字典元素的新增
    scores['王五'] = 85 # 王五是新的键

  • 字典元素的修改
    scores['王五'] = 77 # 对已有键王五的修改

  • 获取字典视图的三个方法
    keys(): 获取字典中所有key
    values(): 获取字典中所有value
    items(): 获取字典中所有key, value对

    # 获取所有的keys
    scores = {'张三':100, '李四': 60}
    keys = scores.keys()
    print(keys)         # dict_keys(['张三', '李四'])
    print(type(keys))   # 
    print(list(keys))   # ['张三', '李四'], 将所有的keys组成的视图转成列表
    
    # 获取所有的values
    values = scores.values()
    print(values)       # dict_values([100, 60])
    print(type(values)) # 
    print(list(values)) # [100, 60]
    
    # 获取所有的键值对
    items = scores.items()
    print(items)        # dict_items([('张三', 100), ('李四', 60)])
    print(type(items))  # 
    print(list(items))  # [('张三', 100), ('李四', 60)], 转换之后的列表元素是由元组组成
    
  • 字典元素的遍历

    scores = {'张三':100, '李四': 60}
    for item in scores:
        print(item, scores[item], scores.get(item))     # 注意item输出的是键
    
7.5 字典生成式
  • 内置函数zip()
    用于将可迭代的对象作为参数,将对象中对应的元素打包成一个元组,然后返回由这些元组组成的列表。
items = ['Fruits', 'Books', 'Others']
prices = [96, 78, 85]
lst = zip(items, prices)
print(lst)
print(list(lst))    # [('Fruits', 96), ('Books', 78), ('Others', 85)]

d = {item.upper():price for item, price in zip(items, prices)}
print(d)        # {'FRUITS': 96, 'BOOKS': 78, 'OTHERS': 85}
8 是排还是散 8.1 元组
  • 什么是元组
    Python内置的数据结构之一,是一个不可变序列。

    不可变序列与可变序列
    不可变序列:没有增、删、改的 *** 作;如:字符串、元组
    可变序列:可以对序列进行增、删、改 *** 作,对象地址不发生更改;如:列表、字典

    # 可变序列
    lst = [10,20]
    print('原序列及id:', lst, id(lst))
    lst.append(30)
    print('修改后的序列及id', lst, id(lst))
    
    # 不可变序列
    s = 'hello'
    print('原字符串及id:', s, id(s))
    s = s + ' world'
    print('修改后的字符串及id:', s, id(s))
    

    问:为什么要将元组设计为不可变序列?
    答:在多任务环境下,同时 *** 作对象时不需要加锁,因此,在程序中尽量使用不可变序列。
    注意事项:元组中存储的是对象的引用
    a)如果元组中的对象本身是不可变对象,则不能再引用其他对象;
    b)如果元组中的对象是可变对象,则可变对象的引用不允许改变,但数据可以改变;

    t = (10, [20, 30], 'hello')
    print(t, type(t))
    print(t[0], type(t[0]), id(t[0]))
    print(t[1], type(t[1]), id(t[1]))
    print(t[2], type(t[2]), id(t[2]))
    # 尝试将t[1]修改为100
    # t[1] = 100
    # print(id(t[1]))    # TypeError,元组不允许修改元素
    # 由于[20, 30]是列表,列表是可变序列,所以可以向列表中添加元素,而列表的内存地址不变
    t[1].append(100)
    print(t[1], id(t[1]))
    t[1][0] = 200
    print(t[1], id(t[1]))
    
  • 元组的创建方式
    使用小括号:t = ('Python', 'hello', 90) (小括号可省略)
    使用内置函数tuple():t = tuple(('Python', 'hello', 90))
    只包含一个元组的元组需要使用逗号和小括号:t = (10, )

    t1 = (1, 2, 3)
    print(t1, type(t1))     # (1, 2, 3) 
    
    t2 = 1, 2, 3            # 省略了小括号
    print(t2, type(t2))     # (1, 2, 3) 
    
    t3 = tuple((1, 2, 3))
    print(t3, type(t3))     # (1, 2, 3) 
    
    t4 = (1)                # 如果元组中只有一个元素,都好不能省
    print(t4, type(t4))     # 1 
    t4 = (1,)
    print(t4, type(t4))     # (1,) 
    
  • 元组的遍历

    t = ('python', 'hello', 99)
    for item in t:
        print(item)
    
8.2 集合
  • 什么是集合
    Python语言提供的内置数据结构。
    与列表、字典一样都属于可变类型的序列。
    集合是没有value的字典。
  • 集合的创建
    使用花括号{}:s = {'Python', 'hello', 90}
    使用内置函数set():s = set(['Python', 'hello', 90])
    使用集合生成式
    s = {'Python', 'hello', 90, 90}      # 集合中的元素不允许重复
    print(s, type(s))                    # {'hello', 'Python', 90} 
    
    s1 = set(range(6))
    print(s1, type(s1))                  # {0, 1, 2, 3, 4, 5} 
    s2 = set(['Python', 'hello', 90])    # 将列表类型的元素转成集合中的元素
    print(s2, type(s2))                  # {'hello', 'Python', 90} 
    s3 = set(('Python', 'hello', 90))    # 将元组类型的元素转成集合中的元素
    print(s3, type(s3))                  # {'hello', 'Python', 90} 
    s4 = set('Python')                   # 将字符串序列转成集合中的元素
    print(s4, type(s4))                  # {'n', 'y', 'P', 'o', 't', 'h'} 
    s5 = {}                              # 不可以使用{}定义空集合,默认类型是dict
    print(s5, type(s5))                  # {} 
    s6 = set()                           # 使用set()定义空集合
    print(s6, type(s6))                  # set() 
    
  • 集合的相关 *** 作
    集合元素的判断:in or not in
    集合元素的新增:.add() # 一次添加一个元素 .update() #至少添加一个元素
    集合元素的删除:.remove() #一次删除一个指定元素,如果指定元素不存在抛出KeyError .discard() #一次删除一个指定元素,如果指定元素不存在不抛出异常 .pop() #一次只删除一个任意元素 .clear() #清空集合
    s = {1, 2, 3}
    # 判断
    print(1 in s)           # True
    print(4 not in s)       # True
    
    # 增
    s.add(4)
    print(s)                # {1, 2, 3, 4}
    s.update([5, 6, 7])
    print(s)                # {1, 2, 3, 4, 5, 6, 7}
    s.update((8, 9))
    print(s)                # {1, 2, 3, 4, 5, 6, 7, 8, 9}
    s.update({10})
    print(s)                # {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
    
    # 删
    # s.remove(11)          # 11不存在,抛错KeyError
    s.remove(1)
    print(s)                # {2, 3, 4, 5, 6, 7, 8, 9, 10}
    s.discard(11)           # 11不存在,不抛异常
    s.discard(2)
    print(s)                # {3, 4, 5, 6, 7, 8, 9, 10}
    # s.pop(10)             # pop方法不能添加参数,抛错TypeError。
    s.pop()
    print(s)                # 用于删除任意一个元素
    s.clear()
    print(s)                # set()
    
  • 集合间的关系
    两个集合是否相等:== !=
    一个集合是否是另一个集合的子集:.issubset()
    一个集合是否是另一个集合的超集:.issuperset()
    两个集合是否没有交集:.isdisjoint()
    # 两个集合是否相等: 元素相同就相等
    s = {1,2,3}
    s2 = {2,3,1}
    print(s == s2)              # True
    print(s != s2)              # False
    
    # 一个集合是否是另一个集合的子集
    s1 = {1, 2, 3, 4}
    s2 = {2, 3, 4}
    s3 = {3, 4, 5}
    print(s2.issubset(s1))      # True, s2是s1的子集
    print(s3.issubset(s1))      # False, s3不是s1的子集
    # 一个集合是否是另一个集合的超集
    print(s1.issuperset(s2))    # True, s1是s2的超集
    print(s1.issuperset(s3))    # False, s1不是s3的超集
    # 两个集合是否没有交集
    print(s2.isdisjoint(s3))    # False, s2和s3有交集
    
  • 集合的数学 *** 作
    交集:.intersection()&
    并集:.union()|
    差集:.difference()
    对称差集:.symmetric_difference()^
    s1 = {10, 20, 30, 40}
    s2 = {20, 30, 40, 50, 60}
    # 交集
    print(s1.intersection(s2))           # {40, 20, 30}
    print(s1 & s2)                       # {40, 20, 30}
    
    # 并集
    print(s1.union(s2))                  # {40, 10, 50, 20, 60, 30}
    print(s1 | s2)                       # {40, 10, 50, 20, 60, 30}
    
    # 差集
    print(s1.difference(s2))             # {10}
    
    # 对称差集
    print(s1.symmetric_difference(s2))   # {50, 10, 60}
    print(s1 ^ s2)                       # {50, 10, 60}
    
  • 集合生成式
    用于生成集合的公式。
    将{}修改为[]就是列表生成式。
    没有元组生成式。
    s = {i*i for i in range(10)}
    print(s)
    
8.3 列表、字典、元组、集合总结
数据结构是否可变是否重复是否有序定义符号
列表(list)可变可重复有序[]
元组(tuple)不可变可重复有序()
字典(dict)可变key不可重复
value可重复
无序{key:value}
集合(set)可变不可重复无序{}
9 一串连一串 9.1 字符串的驻留机制
  • 字符串
    基本数据类型,是一个不可变的字符序列。

  • 驻留机制
    仅保存一份相同且不可变字符串的方法,不同的值被存放在字符串的驻留池中,Python的驻留机制对相同的字符串只保留一份拷贝,后续创建相同字符串时,不会开辟新空间,而是把该字符串的地址赋给新创建的变量。

    a = 'Python'
    b = "Python"
    c = '''Python'''
    print(a, id(a))		# 三个id相同
    print(b, id(b))
    print(c, id(c))
    

  • 驻留机制的几种情况(交互模式)

    1. 字符串的长度为0或1时;
    2. 字符标识符的字符串;
    3. 字符串只在编译时进行驻留,而非运行时;
    4. [-5, 256]之间的整数数字;

    sys中的intern方法强制2个字符串指向同一个对象;
    Pycharm对字符串进行了优化处理(只要内容相同就进行驻留)。

  • 字符串驻留机制的优缺点
    当需要值相同的字符串时,可以直接从字符串池里拿出来使用,避免频繁的创建和销毁,提升效率和节约内存,因此拼接字符串和修改字符串是比较影响性能的。
    在需要进行字符串拼接时建议使用str类型的join方法,而非+。因为join()方法是先计算出所有字符中的长度,然后再拷贝,只new一次对象,效率比用+效率高。

9.2 字符串的常用 *** 作
  • 字符串的查询 *** 作
    s = 'hello, hello'
    print(s.index('lo'))    # 3
    print(s.find('lo'))     # 3
    print(s.rindex('lo'))   # 10
    print(s.rfind('lo'))    # 10
    # print(s.index('a'))   # ValueError
    print(s.find('a'))      # -1
    
    原理图:
  • 字符串的大小写转换 *** 作
    转换之后会产生一个新对象,即使值一样,不驻留!
    s = 'hello, python'
    print(s.upper())     # HELLO, PYTHON
    b = s.lower()
    print(b)             # hello, python
    print(b == s)        # True:b和s值相等
    print(b is s)        # False:b和s内容id不相等,转换产生新对象
    
    s2 = 'hello, Python'
    print(s2.swapcase())    # HELLO, pYTHON
    print(s2.capitalize())  # Hello, python
    print(s2.title())       # Hello, Python
    
  • 字符串的内容对齐 *** 作
    s = 'Hello, Python'
    # 居中对齐
    print(s.center(20, '*'))    # ***Hello, Python****
    print(s.center(20))         #    Hello, Python
    print(s.center(6, '*'))     # Hello, Python 设置宽度<实际宽度,返回原字符串
    # 左对齐
    print(s.ljust(20, '*'))     # Hello, Python*******
    print(s.ljust(20))          # Hello, Python
    print(s.ljust(6, '*'))      # Hello, Python
    # 右对齐
    print(s.rjust(20, '*'))     # *******Hello, Python
    print(s.rjust(20))          #        Hello, Python
    print(s.rjust(6, '*'))      # Hello, Python
    print(s.zfill(20))          # 0000000Hello, Python
    print(s.zfill(6))           # Hello, Python
    print('-1230'.zfill(8))     # -0001230
    
  • 字符串的劈分 *** 作
    s= 'hello world Python'
    lst = s.split()
    print(lst)                              # ['hello', 'world', 'Python']
    s1 = 'hello|world|Python'
    print(s1.split(sep='|'))                # ['hello', 'world', 'Python']
    print(s1.split(sep='|', maxsplit=1))    # ['hello', 'world|Python']
    
    print(s.rsplit())                       # ['hello', 'world', 'Python']
    print(s1.rsplit(sep='|'))               # ['hello', 'world', 'Python']
    print(s1.rsplit(sep='|', maxsplit=1))   # ['hello|world', 'Python']
    
  • 字符串的判断 *** 作
    s= 'hello,python'
    # 是否是合法的标识符
    print(s.isidentifier())               # False
    print('hello_123'.isidentifier())     # True
    print('张三'.isidentifier())           # True
    
    # 是否全部有空字符组成
    print('\t'.isspace())                 # True
    
    # 是否全部由字母组成
    print('abc'.isalpha())                # True
    print('张三'.isalpha())                # True
    print('张三_123'.isalpha())            # False
    
    # 是否全部由十进制的数字组成
    print('123'.isdigit())                # True
    print('123四'.isdigit())              # False
    print('ⅣⅥ'.isdigit())               # False
    
    # 是否全部由数字组成
    print('123'.isnumeric())              # True
    print('123四'.isnumeric())            # True
    print('ⅣⅥ'.isnumeric())              # True
    
    # 是否全部由字母和数字组成
    print('123abc'.isalnum())              # True
    print('张三123'.isalnum())              # True
    print('abc!'.isalnum())                # False
    
  • 字符串的其他 *** 作
    s = 'hello, Python'
    print(s.replace('Python', 'Java'))          # hello, Java
    s1 = 'hello, Python, Python, Python'
    print(s1.replace('Python', 'Java', 2))      # hello, Java, Java, Python
    
    lst = ['hello', 'Java', 'Python']
    print('|'.join(lst))                        # hello|Java|Python
    print(''.join(lst))                         # helloJavaPython
    
    t = ('hello', 'Java', 'Python')
    print(''.join(t))                           # helloJavaPython
    
    print('*'.join('Python'))                   # P*y*t*h*o*n
    
9.3 字符串的比较 *** 作

运算符:>, >=, <, <=, ==, !=
比较规则:首先比较两个字符串中的第一个字符,如果相等则继续比较下一个字符,依次比较下去,直到两个字符串中的字符不相等时,其比较结果就是两个字符串的比较结果,两个字符串中的所有后续字符将不再比较较。
比较原理:两个字符进行相比时,比较的是其ordinal value(原始值),调用内置函数ord可以得到指定字符的ordinal value。与内置函数ord对应的是内置函数chr,调用chr时指定ordinal value可以得到其对应的字符。

注意:a==b比较的是字符串a和b的值是否相等;a is b比较的是a和b内存地址id是否相等。

print('apple' > 'app')      # True
print('apple' > 'banana')   # False
print(ord('a'), ord('b'))   # 97 98
print(chr(97), chr(98))     # a b
9.4 字符串的切片 *** 作

字符串时不可变序列。切片 *** 作将产生新的对象。

s = 'hello,Python'
s1 = s[:5]
print(s1)
s2 = s[6:]
print(s2)
s3 = '!'
new_str = s1 + s3 + s2
print(new_str)
9.5 格式化字符串

格式化字符串的三种方式:

  • %作占位符
  • {}作占位符
  • 使用f字符
name = '张三'
age = 20

print('我叫%s, 今年%d岁。' % (name, age))                      # 我叫张三, 今年20岁。
print('我叫{0},今年{1}岁,我真的叫{0}'.format(name, age))       # 我叫张三,今年20岁,我真的叫张三
print(f'我叫{name},今年{age}岁。')                            # 我叫张三,今年20岁

# 表示宽度
print('%d' % 99)                # 99
print('%10d' % 99)              #         99, 10表示宽度,一共是10位
print('hellohello')             # hellohello

# 表示精度
print('%f' % 3.1415926)          # 3.141593
print('%.3f' % 3.1415926)        # 3.142, .3表示小数点后3位

# 同时表示宽度和精度
print('%10.3f' % 3.1415926)      #      3.142 总宽度为10,小数点后3位

# {}占位符表示宽度和精度
print('{}'.format(3.1415926))        # 3.1415926
print('{0:.3}'.format(3.1415926))    # 3.14, .3表示一共3位
print('{:.3f}'.format(3.1415926))    # 3.142, .3f表示小数点后3位
print('{:10.3f}'.format(3.1415926))  #      3.142.3f,10表示一共10位,3位是小数
9.6 字符串的编码转换
  • 为什么需要字符串的编码转换
  • 编码与解码的方式
    编码:将字符串转换为二进制数据(bytes)
    解码:将bytes类型的数据转换成字符串类型
    s = '天涯共此时'
    # 编码
    # 在GBK编码格式中,一个中文占两个个字节
    print(s.encode(encoding='GBK'))     # b'\xcc\xec\xd1\xc4\xb9\xb2\xb4\xcb\xca\xb1', b表示二进制
    # 在UTF-8编码格式中,一个中文占三个字节
    print(s.encode(encoding='UTF-8'))   # b'\xe5\xa4\xa9\xe6\xb6\xaf\xe5\x85\xb1\xe6\xad\xa4\xe6\x97\xb6'
    
    # 解码
    # byte代表一个二进制数据(字节类型的数据)
    byte = s.encode(encoding='GBK')
    print(byte.decode(encoding='GBK'))    # 天涯共此时
    byte = s.encode(encoding='UTF-8')
    print(byte.decode(encoding='UTF-8'))  # 天涯共此时
    
10 水晶球不调用不动 10.1 函数的创建和调用
  • 什么是函数
    执行特定任务以完成特定功能的一段代码。
  • 为什么需要函数
    复用代码
    隐藏实现细节
    提高可维护性
    提高可读性便于调试
  • 函数的创建和调用
    # 函数的创建
    def 函数名([输入参数]):
        函数体
        [return xxx]
        
    # 函数的调用
    函数名([实际参数])
    
10.2 函数的参数传递


注意:在函数调用过程中,进行参数的传递。如果参数是不可变对象(字符串,元组),在函数体的修改不会影响实参的值!如果是可变对象,在函数体的修改会影响实参的值!

def func(arg1, arg2):
    print('arg1 =', arg1)
    print('arg2 =', arg2)
    arg1 = 100
    arg2.append(10)
    print('arg1 =', arg1)
    print('arg2 =', arg2)

n1 = 11
n2 = [22, 33, 44]
print('n1 =', n1)    # n1 = 11
print('n2 =', n2)    # n2 = [22, 33, 44]
func(n1, n2)         # 位置传参:n1是不可变对象,函数体中arg1的修改不会影响n1的值;n2是可变对象,函数体重arg2的修改会影响n2的值
print('n1 =', n1)    # n1 = 11
print('n2 =', n2)    # n2 = [22, 33, 44, 10]
10.3 函数的返回值
  1. 如果函数没有返回值(函数执行完毕后不需要给调用处提供数据),return可以省略不写;
  2. 函数的返回值如果只有1个,直接返回类型;如果是多个值,返回元组类型。
    def func(num):
        odd = []    # 存奇数
        even = []   # 存偶数
        for i in num:
            if i%2:
                odd.append(i)
            else:
                even.append(i)
        return odd, even
    
    lst = [10, 29, 34, 23, 44, 53, 55]
    print(func(lst))                    # ([29, 23, 53, 55], [10, 34, 44])
    
10.4 函数的参数定义
  • 默认值参数
    函数定义时,给形参设置默认值,只有与默认值不符的时候才需要传递实参。
    def func(a, b=10):
        print(a, b)
    
    func(100)       # 100 10
    func(10, 20)    # 10 20
    
  • 个数可变的位置参数
    在定义函数时,可能无法事先确定传递的位置实参的个数时,使用可变的位置参数。
    使用*定义个数可变的位置参数。
    结果为一个元组。
    def func(*args):
        print(args)
    
    func(1)     # (1,)
    func(1, 2)  # (1, 2)
    
  • 个变可变的关键字形参
    在定义函数时,可能无法事先确定传递的关键字实参的个数时,使用可变的关键字形参。
    使用**定义个数可变的关键字形参。
    结果为一个字典。
    def func(**kwargs):
        print(kwargs)
    
    func(a=10)              # {'a': 10}
    func(a=20, b=30, c=40)  # {'a': 20, 'b': 30, 'c': 40}
    
  • 函数的参数总结
    def func(a, b, c):          # a,b,c在函数的定义处,所以是形参
        print('a = ', a)
        print('b = ', b)
        print('c = ', c)
    
    func(1, 2, 3)               # 位置实参传递
    lst = [10, 20, 30]
    func(*lst)                  # 在函数调用时,将列表中的每个元素都转换为位置实参传入
    func(a=100, c=300, b=200)   # 关键字实参传递
    dic = {'a':1000, 'b':2000, 'c':3000}
    func(**dic)                 # 在函数调用时,将字典中的键值对都转换为关键字实参传入
    
  • 函数定义时的形参的顺序问题
    def func(a, b, *, c, d, **kwargs)   # c d 只能采用关键字实参传递
        pass
    
    def func1(*args, **kwargs):
        pass
    
    def func2(a, b=10, *args, **kwargs):
        pass
    
10.5 变量的作用域

局部变量:在函数内定义并使用的变量,只在函数内部有效,局部变量使用global声明,这个变量就会成全局变量。
全局变量:函数体外定义的变量,可用作于函数内外。

def func(a, b):
    global c    # 局部变量使用global声明,就变成全局变量
    c = a + b
    print(c)
    
func(1, 2)      # 3

name = '张三'    # name的作用域为函数内部和外部都可以使用,全局变量
print(name)     # 张三

def func2():
    print(name)
    
func2()         # 张三
10.6 递归函数
  • 什么是递归函数
    如果在一个函数的函数体内调用了该函数本身,这个函数就称为递归函数。
  • 递归的组成部分
    递归调用与递归终止条件
  • 递归的调用过程
    每递归调用一次函数,都会在栈内存分配一个栈帧;
    每执行完一次函数,都会释放相应的空间。
  • 递归的优缺点
    优点:思路和代码简单
    缺点:占用内存多,效率低下
# 使用递归来计算阶乘
def fac(n):
    if n == 1:
        return 1
    else:
        return n * fac(n-1)

print(fac(6))       # 720
# 斐波那契数列 1 1 2 3 5 ...
def fib(n):
    if n == 1:
        return 1
    if n ==2:
        return 1
    else:
        return fib(n-1) + fib(n-2)

# 斐波那契数列第6位上的数字
print(fib(6))                # 8

# 输出斐波那契数列前6位的数字
for i in range(1, 7):
    print(fib(i))
11 全民来找茬 11.1 Bug的分类
  • 粗心导致的语法错误 SyntaxError
    自查宝典:
    1. 漏了末尾的冒号,如if语句,循环语句,else子句等;
    2. 缩进错误,该缩进的没缩进,不该缩进的瞎缩进;
    3. 把英文符号写成中文符号,比如:引号、冒号、括号;
    4. 字符串拼接时,把字符串和数字拼在一起;
    5. 没有定义变量,比如:while循环条件的变量;
    6. “==”比较运算符和“=”赋值运算符的混用;
    # 语法错误
    age = input('请输入你的年龄:')
    if age >= 18:
        print('成年人,做事需要负法律责任了')
    
    # input返回值为str类型,str与int类型无法进行比较,解决方法法:
    age = input('请输入你的年龄:')
    if int(age) >= 18
        print('成年人,做事需要负法律责任了')
    
  • 知识点不熟练导致得错误
    索引越界问题IndexError
    append()方法的使用掌握不熟练
    # 索引越界
    lst = [1, 2, 3]
    print(lst[3])     # IndexError
    
    # 列表的索引是从0开始的,解决方法:
    lst = [1, 2, 3]
    print(lst[2])
    
    # append使用不当
    lst=[]
    lst = append(1, 2, 3)
    print(lst)
    
    # append是列表的方法,且每次只能加1个元素。解决方法:
    lst = []
    lst.append(1)
    lst.append(2)
    lst.append(3)
    print(lst)
    
  • 思路不清导致得问题
    解决方案:使用print()函数;使用#暂时注释部分代码
  • 被动掉坑
    程序逻辑没有错,只是因为用户错误 *** 作或者一些“列外情况”而导致得程序崩溃。
    解决方案:Python提供了异常处理机制,可以在异常出现时即时捕获,然后内部“消化”,让程序继续运行。
11.3 Python的异常处理机制

try:
    a = int(input('请输入第一个整数:'))
    b = int(input('请输入第二个整数:'))
    result = a/b
    print('%d/%d =' % (a, b), result)
except ZeroDivisionError:
    print('除数不能为0!')
  • 多个except结构
    捕获异常的顺序按照先子类后父类的顺序,为了避免遗漏可能出现的异常,可以在最后增加BaseException。
    try:
        a = int(input('请输入第一个整数:'))
        b = int(input('请输入第二个整数:'))
        result = a/b
        print('%d/%d =' % (a, b), result)
    except ZeroDivisionError:
        print('除数不能为0!')
    except ValueError:
        print('只能输入数字!')
    except BaseException as e:
        print(e)
    

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/799860.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-06
下一篇 2022-05-06

发表评论

登录后才能评论

评论列表(0条)

保存