Python 4:函数、列表、元组、字典、文件 1.函数编程中的函数, 是一段可以被重复使用的代码片段对同一函数针对不同的数据进行计算处理。define--定义1.1语法函数必须先定义再使用函数定义并不会执行函数体内容必须要调用才会执行。1形参列表形式参数0个、1个、多个形参之间用逗号分隔不必指定参数类型支持多种不同类型的参数。2返回值函数的返回值0个、1个、多个返回值之间用逗号分隔编程原则是逻辑和用户交互分离解耦合。3实参列表实际参数需要与形参匹配在调用的时候由调用者把实参传入形参。例求数列的和例返回平面坐标轴的点多个返回值、多元赋值1.2变量的作用域在不同的作用域中允许存在同名的变量变量只能在所在的函数内部生效。在函数内部的变量称为局部变量反之称为全局变量。下面代码中函数内部与外部都有x但只是名字相同不是相同的变量。在函数 getPoint()内部定义的xy只在函数内部生效一旦出了函数的范围这两个变量就不再生效了。如果函数内部尝试访问的变量在局部不存在就会尝试去全局作用域中查找。如果是想在函数内部,修改全局变量的值, 需要使用global关键字声明。1.3函数的执行过程调用方法—传递参数—找到方法地址—执行被调方法的方法体—被调方法结束返回—回到主调方法继续往下执行1.4链式调用把一个函数的返回值作为另一个函数的参数。1.5嵌套调用函数内部还可以调用其他的函数一个函数里面可以嵌套调用任意多个函数。例test 函数内部调用了 print 函数, 这里就属于嵌套调用。例多层嵌套在Python中函数调用关系通过特定的数据结构函数调用栈来维护每次函数调用都会在栈中新增一个栈帧其中保存该函数的局部变量。函数结束时对应栈帧消亡局部变量随之释放通过PyCharm调试器可以查看调用栈和栈帧左下角通常显示调用关系。不同函数中的同名变量属于各自的作用域彼此独立每个变量都保存在对应的栈帧中而栈帧位于内存中因此变量本质上就是一块内存空间。1.6函数递归递归是嵌套调用中的一种特殊情况, 即一个函数自己调用自己。例计算5的阶乘factor-要素。画图或用调试器理解栈溢出函数调用栈中记录每一层函数调用的信息但栈的空间有限若调用层数太多, 就会超出栈的最大范围出现问题。实际开发的时候, 使用递归要慎重视情况选择。为了便于调试可以在函数中添加打印信息但应仅在调试阶段启用正式发布时移除所以需要为形参添加默认值。1.7参数默认值Python 中的函数可以给形参指定默认值带有默认值的参数需要放到没有默认值的参数的后面带有默认值的参数可以在调用的时候不传参。此处 debugFalse 即为参数默认值当我们不指定第三个参数的时候默认 debug 的取值即为False。1.8关键字参数位置参数在调用函数指定实参中默认情况是按照形参的先后顺序来依次传递实参的。关键字参数也可以通过关键字参数调整传参顺序显式指定当前实参传递给哪个形参。Python函数参数中位置参数和关键字参数可以混用但位置参数必须在前。关键字参数常与默认值参数搭配通过设定默认值降低调用成本调用者只需用关键字参数调整所需部分。2.列表list、元组tuple列表一种在代码中批量表示/保存数据的方式创建后元素可修改可变。元组与列表类似但创建后元素不可修改只能整体替换不可变。2.1创建列表 [ ][ ]就是一个空的列表可直接在[ ]中设置初始值允许存放不同类型的元素可直接用print来打印list 中的元素内容。2.2获取、修改元素可以通过下标访问操作符 [ ] 获取列表中的任意元素[ ]中填写的数字称为下标 / 索引从0开始计数也可以取负数表示 倒数第几个元素。可通过下标修改元素的值如果下标超出列表的有效范围会抛出异常。可使用len 函数获取列表的长度元素个数再减一即最大下标。【前面的a[-1]是a[len(a) - 1]的简化写法】2.3切片操作-子列表通过下标操作是一次取出一个元素通过切片操作则是一次取出一组连续的元素相当于得到一个子列表。[start:stop]:Python 的语法结构返回与原序列同类型的新对象遵循前闭后开区间[start, stop)步长默认为1。可以省略前后边界也可以写成负数表示 倒数第几个元素。从开头到倒数第一个元素但不包含倒数第一个元素。切片[start:stop:step]第三个参数 step 可以控制每次迭代提取一个元素后下标索引增加或减少的步长及方向。正数从前往后增加量[start:stop]正着写负数从后往前减少量[start:stop]倒着写当step 的方向与从 start 到 stop的方向不一致时生成空序列step不能为0。若填写的索引数字越界不会报错Python 会自动将越界部分截断到边界或 返回空序列。通常是原序列的一个浅拷贝片段2.4遍历列表元素把列表中元素依次取出来再分别进行处理。1使用 for 循环通过下标访问列表可以修改列表里的值。2使用while循环手动控制下标的变化。通过下标访问列表可以修改列表里的值。2.5插入元素使用append方法, 向列表末尾插入一个元素(尾插)使用insert(位置, 元素)方法, 向任意位置插入一个元素。函数独立存在不依附于任何对象直接通过函数名调用。方法本质上是定义在类内部的函数必须通过对象.方法名()的形式调用。2.6查找元素使用in操作符, 判定元素是否在列表中存在返回值是布尔类型not in则反过来。使用index方法查找元素在列表中的下标返回值是整数如果元素不存在则会抛出异常。2.7删除元素使用pop方法删除最末尾元素也能按照下标来删除元素使用remove方法按照值删除元素。2.8拼接列表使用能够把两个列表拼接在一起会生成一个新的列表不会影响到旧列表的内容。使用extend(延长) /a b方法把一个列表拼接到另一个列表的后面会修改一方内容没有返回值若拿变量接收结果是None。把 b 中的内容拼接到a 的末尾不会修改 b但是会修改a。a a b相对于extend / ab的额外开销构造新的大列表将大列表赋值给 a释放旧列表。2.9元组 ()使用()来表示可直接在()中设置初始值允许存放不同类型的元素可直接用print来打印list 中的元素内容。元组的功能和列表基本一致区别是元组不能修改元素列表可以修改元素。因此元组支持获取元素、切片、遍历、查找元素、拼接 等读操作不支持修改元素、插入元素、删除元素、拼接extend 等写操作。元组在 Python 中很多时候是默认的集合类型如多元赋值。2.10总结如果元素不需要改变, 则优先考虑元组如果元素需要改变, 则优先考虑列表。3.字典dict--键值对字典是一种存储键值对的结构键值对指把键(key)和值(value)进行一对一的映射, 可以根据键快速找到值。一个字典可以同时存储多个键值对字典中的键必须保持唯一不能重复键必须是整数、字符串、元组等不可变类型。如学号是键同学就是值。3.1创建字典 { }使用{ }表示字典可直接在{ }中设置初始值允许存放不同类型的keykey不允许重复可直接用print来打印字典内容。键值对之间使用逗号分割键和值之间使用冒号分割(推荐加一个空格)最后一个键值对后面的逗号可有可无。为了代码更规范美观, 在创建字典的时候往往会把多个键值对, 分成多行来书写。3.2查找key、获取value使用in操作符, 判定key是否在字典中存在返回值是布尔类型not in则反过来。使用[ ]并传入key即可访问字典中对应的value。如果key在字典中不存在, 则会抛出异常。3.3插入、修改、删除元素使用[ ]并根据key来 新增/修改value如果 key不存在写入即新增键值对如果 key存在写入即修改键值对的值。使用pop方法根据 key删除对应的键值对3.4遍历字典元素使用for循环先依次获取字典中的key再获取value最后分别进行处理。C / Java 的哈希表是无序的Python字典做了特殊处理遍历顺序与插入顺序一致。3.5获取key / valuekeys()返回所有 key类似于列表values()返回所有 valueitems()返回所有键值对类似于列表每个元素是一个元组。也可以放入for循环遍历字典元素3.6key的要求字典本质是哈希表key必须可哈希能通过hash() 函数计算出哈希值若报错则不可用。不可变类型如整数、字符串、元组等通常可哈希可变类型如列表、字典等不可哈希。存储器分为内存和硬盘内存中存储数据是以变量的形式程序重启或关机后数据会丢失。4.文件硬盘上存储数据是以文件的形式可以实现数据的持久化存储不会因关机而丢失在 Windows “此电脑”中看到的所有内容本质上都是文件。通过文件后缀名可以区分文件类型如txt、exe、jpg、mp4、docx等我们主要学习文本文件。4.1文件路径文件路径可以看作是文件在硬盘上的身份标识通常使用文件夹也叫目录来整理大量文件层层嵌套的目录结构构成的字符串就称为文件路径用来确定文件所在的位置每个文件对应的路径都是唯一的。如描述QQ.exe文件的位置可以用路径D:\program\qq\Bin\QQ.exeD表示盘符不区分大小写每个\表示一级目录。4.2文件操作要想读写文件, 需要先 打开文件读写完毕之后还要 关闭文件。先创建一个文件夹和txt文件并保存4.3打开文件 open()第一个参数字符串表示要打开的文件路径。第二个参数字符串表示打开方式r读方式read w写方式writea追加写方式append。返回值如果打开成功返回一个文件对象后续的读写操作都围绕这个文件对象展开。此处file为自己为文件对象起的名字打开失败会抛出异常使用完的文件要记得及时关闭4.4关闭文件 close()打开文件实际上是在申请系统资源且计算机的资源是有限的一个程序能打开的文件个数有上限。不再使用文件时应该及时释放资源否则可能会导致文件资源泄露影响程序其他部分正常打开文件。如果循环打开文件而不关闭程序打开的文件数会不断累积直到超过系统上限抛出异常。4.5写文件write()先打开文件再使用write()写文件。使用写方式打开文件w--写方式write如果文件已存在会清空原有内容从开头写入新内容。使用追加写方式打开文件a--追加写方式append如果文件已存在会保留之前的内容在末尾追加新内容。使用读方式打开文件r--读方式read写入时会抛出异常。对于关闭的文件对象系统中与其相关的内存资源已被释放若对其进行写操作也会抛出异常。4.6读文件 read()先使用读方式打开文件r--读方式read。1再使用read()读文件也可以写参数表示 读取几个字符。读取文件中的汉字编码问题在open()中通过encoding参数明确指定正确的编码推荐使用更广泛兼容的UTF-8编码方式这样就能正确读取文件中的汉字了。【 encoding--编码】2读取多行文本使用for循环按行读取Python 会把文件对象当作一个行序列来迭代每次循环读取一行内容读到换行符为止包括换行符 \n并赋值给变量line。print()的end参数控制输出末尾添加的字符默认是\n--换行改为end则表示不额外添加任何内容。3读取所有内容使用readlines()读文件返回一个列表每个元素就是一行内容也是按行读取。总结4.7上下文管理器打开文件后容易忘记关闭Python 提供了上下文管理器with ... as ...来帮助自动关闭文件。使用with 语句打开文件一旦with代码块执行完毕后无论是否发生异常都会自动调用f.close()释放系统资源类似于Java的try with Resources。as f将打开的文件对象赋值给变量 f。