第四章 字符串
- 字符串介绍
1.1字符串是一种用来表示文本的数据类型,它是由符号或者数值组成的一个连续序列。
Eg:'hello itcast' #单引号
"hello itcast" #双引号
"""my name is itcast
my name is itcast""" #三引号
1.2 Python使用反斜杠“\”转义。例如,在字符串中的引号前添加“\”,此时Python解释器会将“\”之后的引号视为解释为一个普通字符,而非特殊符号。
Eg: print('let\'s learn Python
结果:let's learn Python
1.3 转义字符
一些普通字符与反斜杠组合后将失去原有意义,产生新的含义。类似这样的由“\”和而成的、具有特殊意义的字符就是转义字符。转移字符通常用于表示一些无法显示的字符,例如空格、回车等等。
- 格式化字符串
2.1 使用%格式化字符串
格式化字符串是指将指定的字符串转换为想要的格式。Python字符串可通过%格式符格式化输出。
不同的占位符为不同类型的变量预留位置,常见的占位符如下所示。
2.2 使用format()方法格式化字符串
虽然使用%可以对字符串进行格式化,但是这种方式并不是很直观,一旦开发人员遗漏了替换数据或选择了不匹配的格式符,就会导致字符串格式化失败。为了能更直观、便捷地格式化字符串,Python为字符串提供了一个格式化方法format()。
Str.format(values)
字符串 真实数据
2.3 使用f-string格式化字符串
f-string提供了一种更为简洁的格式化字符串的方式,它在形式上以f或F引领字符串,在字符串中使用“{变量名}”标明被替换的真实数据和其所在位置。
格式:f('{变量名}') or F('{变量名}')
3.字符串的常见操作
3.1 字符串的查找与替换
Python中提供了实现字符串查找操作的find()方法,该方法可查找字符串中是否包含子串,若包含则返回子串首次出现的位置,否则返回-1。
格式:str.split(sep=None, maxsplit=-1)
##sep:分隔符,默认为空字符。
#maxsplit:分割次数,默认值为-1,
#表示不限制分割次数
代码:string= "Hello, my name is Wang Hong"
# 以空格作为分割符,并分割2次
print(string.split(' ', 2))
结果:['Hello,', 'my', 'name is Wang Hong']
3.2.1字符串的分隔与拼接
split()方法可以按照指定分隔符对字符串进行分割,该方法会返回由分割后的子串组成的列表。
格式:str.split(sep=None, maxsplit=-1)
#sep:分隔符,默认为空字符。
#maxsplit:分割次数,默认值为-1,
# 表示不限制分割次数。
代码:string= "Hello, my name is Wang Hong"
# 以空格作为分割符,并分割2次
print(string.split(' ', 2))3.2
结果:['Hello,', 'my', 'name is Wang Hong']
3.2.2字符串的分隔与拼接
join()方法使用指定的字符连接字符串并生成一个新的字符串。join()方法的语法格式如下。
格式:str.join(iterable)
#iterable:表示连接字符串的字符
代码:symbol = '*'
world = 'Python'
print(symbol.join(world))
结果: P*y*t*h*o*n
3.2.3删除字符串的指定字符
字符串中可能会包含一些无用的字符(如空格),在处理字符串之前往往需要先删除这些无用的字符。Python中的strip()、lstrip()和rstrip()方法可以删除字符串中的指定字符。
在特定情况下会对英文单词的大小写形式进行要求,表示特殊简称时全字母大写,如CBA;表示月份、周日、节假日时每个单词首字母大写,如Monday。Python中支持字母大小写转换的方法有upper()、lower()、capitalize()和title()。
3.2.4 字符串对齐
在使用Word处理文档时可能需要对文档的格式进行调整,如标题居中显示、左对齐、右对齐等。Python提供了center()、ljust()、rjust()这3个方法来设置字符串的对齐方式。
第五章 组合数据类型
- 认识组合数据类型
- 认识组合数据类型
Python中常用的序列类型有字符串、列表和元组。
Python中的序列支持双向索引:正向递增索引和反向递减索引正向递增索引从左向右依次递增,第一个元素的索引为0,第二个元素的索引为1,以此类推;反向递减索引从右向左依次递减,从右数第一个元素的索引为-1,第二个元素的索引为-2,以此类推
Python集合具备确定性、互异性和无序性三个特性。Python要求放入集合中的元素必须是不可变类型,Python中的整型、浮点型、字符串类型和元组属于不可变类型,列表、字典及集合本身都属于可变的数据类型。
确定性:给定一个集合,那么任何一个元素是否在集合中就确定了。
互异性:集合中的元素互不相同。
无序性:集合中的元素没有顺序,顺序不同但元素相同的集合可视为同一集合。
- 列表
2.1 创建列表
Python列表的创建方式非常简单,既可以直接使用中括号“[]”创建,也可以使用内置的list()函数快速创建。
Eg:list_one = [] # 使用[]创建空列表
li_two = list() # 使用list()创建空列表
在Python中,支持通过for…in…语句迭代获取数据的对象就是可迭代对象。目前,我们学习过可迭代的类型有字符串和列表,后续学习的集合、字典、文件也是可迭代类型的对象。使用isinstance()函数可以判断目标是否为可迭代对象,返回True表示为可迭代对象。
Eg:from collections.abc import Iterable
ls = [3,4,5]
print(isinstance(ls, Iterable))
2.2 访问列表元素
列表中的元素可以通过索引或切片这两种方式进行访问,也可以在循环中依次访问。
Eg:list_one = ["Java", "C#", "Python", "PHP"]
print(list_one[1]) #索引
print(list_one[1]) #切片
for li in li_one:
print(li, end=' ') #循环
2.3 添加列表元素
向列表中添加元素是非常常见的一种列表操作,Python提供了append()、extend()和insert()这几个方法。
Eg:list_one = ["Java", "C#", "Python", "PHP"]
list_one.append("C++") #append(在列表末尾添加元素)
list_one.extend([["Android", "IOS",]]) #extend(在列表末尾添加另一个序列的所有元素)
list_one.insert(2,"HTML") #insert(按照索引将元素插入列表的指定位置)
2.4元素排序
列表的排序是将元素按照某种规定进行排列。列表中常用的排序方法有sort()、reverse()、sorted()。
li_one = [6, 2, 5, 3] #示例
list_one.sort() #sort 有序的元素会覆盖原来的列表元素,不产生新列表
li_two = sorted(li_one) #sorted 产生排序后的新列表,排序操作不会对原列表产生影响
li_one.reverse() #reverse 逆置列表,即把原列表中的元素从右至左依次排列存放
2.5 删除列表元素
删除列表元素的常用方式有del语句、remove()方法、pop()方法和clear()方法。
li_one = [6, 2, 5, 3] #示例
del li_one[0] #del 删除列表中指定位置的元素
li_one.remove(3) #remove 移除列表中匹配到的第一个元素
li_one.pop() #pop 移除列表中的某个元素,若未指定具体元素,则移除列表中的最后一个元素
li_one.clear() #clear 清空列表
2.6 列表推导式
列表推导式是符合Python语法规则的复合表达式,它用于以简洁的方式根据已有的列表构建满足特定需求的列表。列表推导式的基本格式如下:
[exp for x in list]
列表推导式还可以结合if判断语句或for循环嵌套,生成更灵活的列表。
- 带有if语句的列表推导式
- for循环嵌套的列表推导式
- 带有if语句与for循环嵌套的列表推导式
- 元组
元组的表现形式为一组包含在圆括号“()”中、由逗号分隔的元素,元组中元素的个数、类型不受限制。除了使用()构建元组外,还可以使用内置函数tuple()构建元组。
t1 = 0 ##使用()构建元组
t2 = tuple ##使用tuple构建元组
当使用圆括号“()”创建元组时,如果元组中只包含一个元素,那么需要在该元素的后面添加逗号,从而保证Python解释器能够识别其为元组类型。
t1 = ('python')
t2 = ('python',)
print(type(t1))
print(type(t2))
输出结果:<class 'str'>
<class 'tuple'>
元组支持以索引和切片方式访问元组的元素,也支持在循环中遍历元组。
tuple_demo = ('p','y','t', 'h', 'o','n') # 示例
tuple_demo[2] #使用索引
tuple_demo[2:5] #使用切片
for i in tuple_demo:
print(i) #遍历元组
- 集合
Python的集合(set)本身是可变类型,但Python要求放入集合中的元素必须是不可变类型。大括号“{}”或内置函数set()均可构建集合。
s1 = {1} #使用{}构建集合
s2 = set{[1,2]} #使用set构建元组
需要注意,使用{}不能创建空集合(不包含元素的{}创建的是字典变量),空集合只能利用set()函数创建。
set_demo1 = {}
set_demo2 = set()
print(type(set_demo1))
print(type(set_demo2))
输出结果:<class 'dict'>
<class 'set'>
集合是可变的,集合中的元素可以动态增加或删除。Python提供了一些内置方法来操作集合,常见内置方法如下:
集合也可以利用推导式创建,集合推导式的格式与列表推导式相似,区别在于集合推导式外侧为大括号“{}”,具体如下:
{exp for x in set if cond}
- 字典
5.1 创建字典
字典的表现形式为一组包含在大括号“{}”中的键值对,每个键值对为一个字典元素,每个元素通过逗号“,”分隔,每对键值通过“:”分隔,除了使用“{}”创建字典还可以使用内置函数dict创建字典。
d1 = {'A':123,12:'Python'} #使用{}构建集合
d2 = dict({'A':'123','B':'135'}) #使用dict构建元组
5.2 字典的访问
d2 = dict({'A':'123','B':'135'}) #使用dict构建元组
d2['A'] #键 ‘123’
d2.get('B') #get() '135'
字典涉及的数据分为键、值和元素(键值对),除了直接利用键访问值外,Python还提供了内置方法keys()、values()和items()。
info = {'name': 'Jack','age':23,'height':185}
info.keys() #获取所有键 dict_keys(['name', 'age', 'height'])
info.values() #获取所有值 dict_values(['Jack', 23, 185])
info.items() #获取所有元素 dict_items([('name', 'Jack'), ('age', 23), ('height', 185)])
5.3 元素的添加和修改
字典支持通过为指定的键赋值或使用update()方法添加或修改元素,下面分别介绍如何添加和修改字典元素。
通过键添加元素:字典变量[键] = 值
使用update()添加元素:dict.update(key=value)
字典支持通过为指定的键赋值或使用update()方法添加或修改元素,下面分别介绍如何添加和修改字典元素。
add_dict= {'name': 'Jack','age':23,'height':185}
add_dict['sco'] = 98 #通过键添加
add_dict.update(sco=98) #使用update方法添加
修改字典元素的本质是通过键获取值,再重新对元素进行赋值。修改元素的操作与添加元素的操作相同。
modify_dict = {'stu1': '小明', 'stu2': '小刚', 'stu3': '小兰'}
modify_dict['stu3'] = '刘婷' #通过键修改
modify_dict.update(stu2='张强') #使用updat方法修改
5.4 字典元素的删除
Python支持通过pop()、popitem()和clear()方法删除字典中的元素
pop():根据指定键值删除字典中的指定元素
popitem():随机删除字典中的元素
clear():清空字典中的元素
字典推导式外侧为大括号“{}”,且内部需包含键和值两部分,具体格式如下
{new_key:new_value for key,value in dict.items()}
利用字典推导式可快速交换字典中的键和值,示例如下:
old_dict = {'name': 'Jack','age':23,'height':185}
new_dict = {value:key for key,value in old_dict.items()}
print(new_dict)
输出结果:{'Jack': 'name', 23: 'age', 185: 'height'}
- 组合数据类型与运算符
Python中针对数字类型的运算符对组合数据类型同样适用,包括+、*、in、not in。
字符串、列表和元组使用“ + ”运算符,会对数据进行拼接
字符串、列表和元组使用“ * ”运算符,会对数据进行整数倍拼接
“in”“not in”运算符称为成员运算符,用于判断某个元素是否属于某个变量
第六章 函数
1.函数概述
函数是组织好的、实现单一功能或相关联功能的代码段。我们可以将函数视为一段有名字的代码,这类代码可以在需要的地方以“函数名()”的形式调用。
格式:print()
input()
函数式编程具有以下优点:
将程序模块化,既减少了冗余代码,又让程序结构更为清晰
提高开发人员的编程效率
方便后期的维护与扩展
2.函数的定义与调用
2.1定义函数
前面使用的print()函数和input()都是Python的内置函数,这些函数由Python定义。开发人员也可以根据自己的需求定义函数,Python中使用关键字def来定义函数,其语法格式如下:
def 函数名([参数列表]):
["""文档字符串"""]
函数体
[return语句]
2.2调用函数
函数在定义完成后不会立刻执行,直到被程序调用时才会执行。
语法格式如下: 函数名([参数列表]):
函数内部也可以调用其他函数,这被称为函数的嵌套调用。
def add_modify(a, b):
result = a + b
add()
print(result)
add_modify(10, 20)
函数在定义时可以在其内部嵌套定义另外一个函数,此时嵌套的函数称为外层函数,被嵌套的函数称为内层函数。
def add_modify(a, b):
result = a + b
print(result)
def test():
print("我是内层函数")
add_modify(10, 20)
3.函数参数的传递
3.1位置参数的传递
我们通常将定义函数时设置的参数称为形式参数(简称为形参),将调用函数时传入的参数称为实际参数(简称为实参)。函数的参数传递是指将实际参数传递给形式参数的过程。
函数参数的传递可以分为位置参数传递、关键字参数传递、默认参数传递、参数的打包与解包以及混合传递。
函数在被调用时会将实参按照相应的位置依次传递给形参,也就是说将第一个实参传递给第一个形参,将第二个实参传递给第二个形参,以此类推。
def get_max(a, b):
if a > b:
print(a,"是较大的值!")
else:
print(b,"是较大的值!")
get_max(8, 5)
3.2 关键字参数的传递
关键字参数的传递是通过“形参=实参”的格式将实参与形参相关联,将实参按照相应的关键字传递给形参。
def connect(ip, port):
print(f"设备{ip}:{port}连接!")
connect(ip="127.0.0.1", port=8080)
无论实参采用位置参数的方式传递,还是关键字参数的方式传递,每个形参都是有名称的,怎么区分用哪种方式传递呢?
符号“/”
Python在3.8版本中新增了仅限位置形参的语法,使用符号“/”来限定部分形参只接收采用位置传递方式的实参。
def func(a, b, /, c):
print(a, b, c)
3.3 默认参数的传递
函数在定义时可以指定形参的默认值,如此在被调用时可以选择是否给带有默认值的形参传值,若没有给带有默认值的形参传值,则直接使用该形参的默认值。
def connect(ip, port=8080):
print(f"设备{ip}:{port}连接!")
connect(ip="127.0.0.1")
connect(ip="127.0.0.1", port=3306)
输出结果:设备127.0.0.1:8080连接!
设备127.0.0.1:3306连接!
3.4参数的打包于解包
3.4.1 打包
如果函数在定义时无法确定需要接收多少个数据,那么可以在定义函数时为形参添加“*”或“**”:
“*” —— 接收以元组形式打包的多个值
“**”—— 接收以字典形式打包的多个值
“*”
def test(*args):
print(args)
test(11,22,33,44,55)
输出结果:(11, 22, 33, 44, 55)
“**”
def test(**kwargs):
print(kwargs)
test(a=11, b=22, c=33, d=44, e=55)
输出结果:{'a': 11, 'b': 22, 'c': 33, 'd': 44, 'e': 55}
虽然函数中添加“*”或“**”的形参可以是符合命名规范的任意名称,但这里建议使用*args和**kwargs。
若函数没有接收到任何数据,参数*args和**kwargs为空,即它们为空元组或空字典。
3.4.2 解包
实参是元组 → 可以使用“*”拆分成多个值 → 按位置参数传给形参
实参是字典 → 可以使用“**” 拆分成多个键值对 → 按关键字参数传给形参
def test(a, b, c, d, e):
print(a, b, c, d, e)
nums = (11, 22, 33, 44, 55)
test(*nums)
输出结果:{'a': 11, 'b': 22, 'c': 311 22 33 44 553, 'd': 44, 'e': 55}
3.5 混合传递
前面介绍的参数传递的方式在定义函数或调用函数时可以混合使用,但是需要遵循一定的规则,具体规则如下。
优先按位置参数传递的方式。
然后按关键字参数传递的方式。
之后按默认参数传递的方式。
最后按打包传递的方式。
在定义函数时:
带有默认值的参数必须位于普通参数之后。
带有“*”标识的参数必须位于带有默认值的参数之后。
带有“**”标识的参数必须位于带有“*”标识的参数之后。
def test(a, b, c=33, *args, **kwargs):
print(a, b, c, args, kwargs)
test(1, 2)
test(1, 2, 3)
test(1, 2, 3, 4)
test(1, 2, 3, 4, e=5)
输出结果:1 2 33 () {}
1 2 3 () {}
1 2 3 (4,) {}
1 2 3 (4,) {'e': 5}
5,函数的返回值
函数中的return语句会在函数结束时将数据返回给程序,同时让程序回到函数被调用的位置继续执行。
def filter_sensitive_words(words):
if "山寨" in words:
new_words = words.replace("山寨", "**")
return new_words
result = filter_sensitive_words("这个手机是山寨版吧!")
print(result)
输出结果:这个手机是**版吧!
如果函数使用return语句返回了多个值,那么这些值将被保存到元组中。
def move(x, y, step):
nx = x + step
ny = y - step
return nx, ny # 使用return语句返回多个值
result = move(100, 100, 60)
print(result)
输出结果:(160, 40)
5,变量作用域
变量并非在程序的任意位置都可以被访问,其访问权限取决于变量定义的位置,其所处的有效范围称为变量的作用域。
根据作用域的不同,变量可以划分为局部变量和全局变量。
5.1 局部变量和全局变量
函数内部定义的变量,只能在函数内部被使用
函数执行结束之后局部变量会被释放,此时无法再进行访问。
5.1.1 局部变量
def test_one():
number = 10 # 局部变量
print(number) # 函数内部访问局部变量
test_one()
print(number) # 函数外部访问局部变量
不同函数内部可以包含同名的局部变量,这些局部变量的关系类似于不同目录下同名文件的关系,它们相互独立,互不影响。
def test_one():
number = 10
print(number) # 访问test_one()函数的局部变量number
def test_two():
number = 20
print(number) # 访问test_two()函数的局部变量number
test_one()
test_two()
输出结果:10
20
5.2.2 全局变量
全局变量可以在整个程序的范围内起作用,它不会受到函数范围的影响。
number = 10 # 全局变量
def test_one():
print(number) # 函数内部访问全局变量
test_one()
print(number)
输出结果:10
10
全局变量在函数内部只能被访问,而无法直接修改。
# 定义全局变量
number = 10
def test_one():
print(number)
number += 1
test_one()
print(number)
这是因为函数内部的变量number视为局部变量,而在执行“number+=1”这行代码之前并未声明过局部变量number。
5.2 global和nonlocal关键字
函数内部无法直接修改全局变量或在嵌套函数的外层函数声明的变量,但可以使用global或nonlocal关键字修饰变量以间接修改以上变量。
5.2.1 global关键字
使用global关键字可以将局部变量声明为全局变量,其使用方法如下:
global 变量
number = 10 # 定义全局变量
def test_one():
global number # 使用global声明变量number为全局变量
number += 1
print(number)
test_one()
print(number)
5.2.2 nonlocal关键字
使用nonlocal关键字可以在局部作用域中修改嵌套作用域中定义的变量,其使用方法如下:
nonlocal 变量
def test():
number = 10
def test_in():
nonlocal number
number = 20
test_in()
print(number)
test()
6 特殊形式的函数
1.递归函数
函数在定义时可以直接或间接地调用其他函数。若函数内部调用了自身,则这个函数被称为递归函数。
递归函数在定义时需要满足两个基本条件:一个是递归公式,另一个是边界条件。其中:
递归公式是求解原问题或相似的子问题的结构;
边界条件是最小化的子问题,也是递归终止的条件。
递归函数的执行可以分为以下两个阶段:
1.递推:递归本次的执行都基于上一次的运算结果。
2.回溯:遇到终止条件时,则沿着递推往回一级一级地把值返回来。
格式:def函数名([参数列表]):
if 边界条件:
rerun 结果
else:
return 递归公式
2.匿名函数
匿名函数是一类无需定义标识符的函数,它与普通函数一样可以在程序的任何位置使用。Python中使用lambda关键字定义匿名函数,它的语法格式如下:
lambda <形式参数列表> :<表达式>
匿名函数与普通函数的主要区别如下:
普通函数在定义时有名称,而匿名函数没有名称;
普通函数的函数体中包含有多条语句,而匿名函数的函数体只能是一个表达式;
普通函数可以实现比较复杂的功能,而匿名函数可实现的功能比较简单;
普通函数能被其他程序使用,而匿名函数不能被其他程序使用。
定义好的匿名函数不能直接使用,最好使用一个变量保存它,以便后期可以随时使用这个函数。
# 定义匿名函数,并将它返回的函数对象赋值给变量temp
temp = lambda x : pow(x, 2)
temp(10)
第七章 文件与数据的格式化
1,文件概述
文件标识:文件标识的意义:找到计算机中唯一确定的文件。
文件标识的组成:文件路径、文件名主干、文件扩展名。
操作系统以文件为单位对数据进行管理。
文件类型:根据数据的逻辑存储结构,人们将计算机中的文件分为文本文件和二进制文件。
文本文件:专门存储文本字符数据。
二进制文件:不能直接使用文字处理程序正常读写,必须先了解其结构和序列化规则,再设计正确的反序列化规则,才能正确获取文件信息。
- 二进制文件和文本文件这两种类型的划分基于数据逻辑存储结构而非物理存储结构,计算机中的数据在物理层面都以二进制形式存储。
标准文件:Python的sys模块中定义了3个标准文件,分别为:
stdin(标准输入文件)。标准输入文件对应输入设备,如键盘。
stdout(标准输出文件)。
stderr(标准错误文件)。标准输出文件和标准错误文件对应输出设备,如显示器。
Eg:import sys
file = sys.stdout
file.write("hello")
2.文件的基础操作
文件的打开、关闭与读写是文件的基础操作,任何更复杂的文件操作都离不开这些操作。
2.1 打开文件
内置函数open()用于打开文件,该方法的声明如下:
open(file, mode='r', buffering=-1)
打开模式 | 名称 | 描述 | |
r/rb | 只读模式 | 以只读的形式打开文本文件/二进制文件,若文件不存在或无法找到,文件打开失败 | |
w/wb | 只写模式 | 以只写的形式打开文本文件/二进制文件,若文件已存在,则重写文件,否则创建新文件 | |
a/ab | 追加模式 | 以只写的形式打开文本文件/二进制文件,只允许在该文件末尾追加数据,若文件不存在,则创建新文件 | |
r+/rb+ | 读取(更新)模式 | 以读/写的形式打开文本文件/二进制文件,若文件不存在,文件打开失败 |
|
w+/wb+ | 写入(更新)模式 | 以读/写的形式打开文本文件/二进制文件,若文件已存在,则重写文件 | |
a+/ab+ | 追加(更新)模式 | 以读/写的形式打开文本/二进制文件,只允许在文件末尾添加数据,若文件不存在,则创建新文件 |
2.1文件的打开与关闭
内置函数open()用于打开文件,该方法的声明如下:
open(file, mode='r', buffering=-1)
2.关闭文件
Python可通过close()方法关闭文件,也可以使用with语句实现文件的自动关闭。
2.文件的读写
Python可通过close()方法关闭文件,也可以使用with语句实现文件的自动关闭。Python可通过close()方法关闭文件,也可以使用with语句实现文件的自动关闭。
2.2 读取文件——read(方法)
read()方法可以从指定文件中读取指定字节的数据,其语法格式如下:
read(n=-1)
with open('file.txt', mode='r') as f:
print(f.read(2)) # 读取两个字节的数据
print(f.read())
2.3 readline()文件
readline()方法可以从指定文件中读取一行数据,其语法格式如下:
readline()
with open('file.txt', mode='r', encoding='utf-8') as f:
print(f.readline())
print(f.readline())
readlines()方法可以一次读取文件中的所有数据,若读取成功,该方法会返回一个列表,文件中的每一行对应列表中的一个元素。语法格式如下:
readlines(hint=-1)
with open('file.txt', mode='r', encoding='utf-8') as f:
print(f.readlines())
2.写文件
2.1 write
write()方法可以将指定字符串写入文件,其语法格式如下:
write(data)
以上格式中的参数data表示要写入文件的数据,若数据写入成功,write()方法会返回本次写入文件的数据的字节数。
string = "Here we are all, by day; by night." # 字符串
with open('write_file.txt', mode='w', encoding='utf-8') as f:
size = f.write(string) # 写入字符串
print(size)
文本文件支持多种编码方式,不同编码方式下字符与字节的对应关系不同,常见的编码方式以及字符与字节的对应关系如表所示。
编码方式 | 语言 | 字符数 | 字节数 |
ASCII | 中文 | 1 | 2 |
英文 | 1 | 1 | |
UTF-8 | 中文 | 1 | 3 |
英文 | 1 | 1 | |
Unicode | 中文 | 1 | 2 |
英文 | 1 | 2 | |
GBK | 中文 | 1 | 2 |
英文 | 1 | 1 |
Tell
tell()方法用于获取文件当前的读写位置,以操作文件file.txt为例,tell()的用法如下:
with open('file.txt') as f:
print(f.tell()) # 获取文件读写位置
print(f.read(5)) # 利用read()方法移动文件读写位置
print(f.tell()) # 再次获取文件读写位置
seek
Python提供了seek()方法,使用该方法可控制文件的读写位置,实现文件的随机读写。seek()方法的语法格式如下:
seek(offset, from)
offset:表示偏移量,即读写位置需要移动的字节数。
from:用于指定文件的读写位置,该参数的取值为0、1、2。
Python提供了seek()方法,使用该方法可控制文件的读写位置,实现文件的随机读写。seek()方法的语法格式如下:
seek(offset, from)
with open('file.txt') as f:
print(f.tell()) # 获取文件读写位置
print(f.read(5)) # 利用read()方法移动文件读写位置
print(f.tell()) # 再次获取文件读写位置
需要注意的是,在Python3中,若打开的是文本文件,那么seek()方法只允许相对于文件开头移动文件位置,若在参数from值为1、2的情况下对文本文件进行位移操作,将会产生错误。
with open('file.txt') as f:
f.seek(5,0) # 相对文件开头移动5字节
f.seek(3,1)
若要相对当前读写位置或文件末尾进行位移操作,需以二进制形式
with open('file.txt','rb') as f:
f.seek(5,0)
f.seek(3,1)
3.文件与目录的管理
管理文件与目录
- 删除文件——os.remove(文件名)
- 文件重命名——os.rename(原文件名,新文件名)
- 创建/删除目录——os.mkdir(目录名)/os.rmdir(目录名)
- 获取当前目录——os.getcwd()
- 更改默认目录——os.chdir(路径名)
- 获取目录列表——os.listdir(目录/路径)
4.数据维度域数据格式化
一二维数据的存储与读写
1.数据存储
一维数据呈线性排列,一般用特殊字符分隔,例如:
- 使用空格分隔:成都 杭州 重庆 武汉 苏州 西安 天津
- 使用逗号分隔:成都,杭州,重庆,武汉,苏州,西安,天津
- 使用&分隔:成都&杭州&重庆&武汉&苏州&西安&天津
一维数据的存储需要注意以下几点:
- 同一文件或同组文件一般使用同一分隔符分隔。
- 分隔数据的分隔符不应出现在数据中。
- 分隔符为英文半角符号,一般不使用中文符号作为分隔符。
- 二维数据可视为多条一维数据的集合,当二维数据只有一个元素时,这个二维数据就是一维数据。
CSV(Commae-Separeted Values,逗号分隔值)是国际上通用的一二维数据存储
CSV格式规范:
- 以纯文本形式存储表格数据
- 文件的每一行对应表格中的一条数据记录
- 每条记录由一个或多个字段组成
- 字段之间使用逗号(英文、半角)分隔
- CSV也称字符分隔值,具体示例如下:
- 姓名,语文,数学,英语,理综
- 刘婧,124,137,145,260
- 张华,116,143,139,263
- 邢昭林,120,130,148,255
- 鞠依依,115,145,131,240
- 黄丽萍,123,108,121,235
- 赵越,132,100,112,210
2.数据读取
- Windows平台中CSV文件的后缀名为.csv,可通过Office Excel或记事本打开
- Python在程序中读取.csv文件后会以二维列表形式存储其中内容
- csv_file = open('score.csv') lines = [] for line in csv_file: line = line.replace('\n','') lines.append(line.split(',')) print(lines) csv_file.close()
3.数据写入
将一、二维数据写入文件中,即按照数据的组织形式,在文件中添加新的数据。
多维数据的格式化
为了直观地表示多维数据,也为了便于组织和操作,三维及以上的多维数据统一采用键值对的形式进行格式化。
网络平台上传递的数据大多是高维数据,JSON是网络中常见的高维数据格式。JSON格式的数据遵循以下语法规则:
- 数据存储在键值对(key:value)中,例如“姓名”: “张华”。
- 数据的字段由逗号分隔,例如“姓名”: “张华”, “语文”: “116”。
- 一个花括号保存一个JSON对象,例如{“姓名”: “张华”, “语文”: “116”}。
- 一个方括号保存一个数组,例如[{“姓名”: “张华”, “语文”: “116”}]。
- “高三二班考试成绩”:[ {“姓名”: “陈诚”, “语文”: “124”, “数学”: “127”, “英语”: “145”, “理综”: “259” }; {“姓名”: “黄思”, “语文”: “116”, “数学”: “143”, “英语”: “119”, “理综”: “273” }; …… ]
- <高三二班考试成绩> <姓名>陈诚</姓名><语文>124</语文><数学>127<数学/><英语>145<英语/><理综>259<理综/> <姓名>黄思</姓名><语文>116</语文><数学>143<数学/><英语>119<英语/><理综>273<理综/> …… </高三二班考试成绩>
JSON模块——json
利用json模块的dumps()函数和loads()函数可以实现Python对象和JSON数据之间的转换,这两个函数的具体功能如表所示。
函数 | 功能 |
dumps() | 对Python对象进行转码,将其转化为JSON字符串 |
loads() | 将JSON字符串解析为Python对象 |
Dumps()函数
使用dumps()函数对Python对象进行转码。
Loads()函数
第四章 字符串
- 字符串介绍
1.1字符串是一种用来表示文本的数据类型,它是由符号或者数值组成的一个连续序列。
Eg:'hello itcast' #单引号
"hello itcast" #双引号
"""my name is itcast
my name is itcast""" #三引号
1.2 Python使用反斜杠“\”转义。例如,在字符串中的引号前添加“\”,此时Python解释器会将“\”之后的引号视为解释为一个普通字符,而非特殊符号。
Eg: print('let\'s learn Python
结果:let's learn Python
1.3 转义字符
一些普通字符与反斜杠组合后将失去原有意义,产生新的含义。类似这样的由“\”和而成的、具有特殊意义的字符就是转义字符。转移字符通常用于表示一些无法显示的字符,例如空格、回车等等。
- 格式化字符串
2.1 使用%格式化字符串
格式化字符串是指将指定的字符串转换为想要的格式。Python字符串可通过%格式符格式化输出。
不同的占位符为不同类型的变量预留位置,常见的占位符如下所示。
2.2 使用format()方法格式化字符串
虽然使用%可以对字符串进行格式化,但是这种方式并不是很直观,一旦开发人员遗漏了替换数据或选择了不匹配的格式符,就会导致字符串格式化失败。为了能更直观、便捷地格式化字符串,Python为字符串提供了一个格式化方法format()。
Str.format(values)
字符串 真实数据
2.3 使用f-string格式化字符串
f-string提供了一种更为简洁的格式化字符串的方式,它在形式上以f或F引领字符串,在字符串中使用“{变量名}”标明被替换的真实数据和其所在位置。
格式:f('{变量名}') or F('{变量名}')
3.字符串的常见操作
3.1 字符串的查找与替换
Python中提供了实现字符串查找操作的find()方法,该方法可查找字符串中是否包含子串,若包含则返回子串首次出现的位置,否则返回-1。
格式:str.split(sep=None, maxsplit=-1)
##sep:分隔符,默认为空字符。
#maxsplit:分割次数,默认值为-1,
#表示不限制分割次数
代码:string= "Hello, my name is Wang Hong"
# 以空格作为分割符,并分割2次
print(string.split(' ', 2))
结果:['Hello,', 'my', 'name is Wang Hong']
3.2.1字符串的分隔与拼接
split()方法可以按照指定分隔符对字符串进行分割,该方法会返回由分割后的子串组成的列表。
格式:str.split(sep=None, maxsplit=-1)
#sep:分隔符,默认为空字符。
#maxsplit:分割次数,默认值为-1,
# 表示不限制分割次数。
代码:string= "Hello, my name is Wang Hong"
# 以空格作为分割符,并分割2次
print(string.split(' ', 2))3.2
结果:['Hello,', 'my', 'name is Wang Hong']
3.2.2字符串的分隔与拼接
join()方法使用指定的字符连接字符串并生成一个新的字符串。join()方法的语法格式如下。
格式:str.join(iterable)
#iterable:表示连接字符串的字符
代码:symbol = '*'
world = 'Python'
print(symbol.join(world))
结果: P*y*t*h*o*n
3.2.3删除字符串的指定字符
字符串中可能会包含一些无用的字符(如空格),在处理字符串之前往往需要先删除这些无用的字符。Python中的strip()、lstrip()和rstrip()方法可以删除字符串中的指定字符。
在特定情况下会对英文单词的大小写形式进行要求,表示特殊简称时全字母大写,如CBA;表示月份、周日、节假日时每个单词首字母大写,如Monday。Python中支持字母大小写转换的方法有upper()、lower()、capitalize()和title()。
3.2.4 字符串对齐
在使用Word处理文档时可能需要对文档的格式进行调整,如标题居中显示、左对齐、右对齐等。Python提供了center()、ljust()、rjust()这3个方法来设置字符串的对齐方式。
第五章 组合数据类型
- 认识组合数据类型
- 认识组合数据类型
Python中常用的序列类型有字符串、列表和元组。
Python中的序列支持双向索引:正向递增索引和反向递减索引正向递增索引从左向右依次递增,第一个元素的索引为0,第二个元素的索引为1,以此类推;反向递减索引从右向左依次递减,从右数第一个元素的索引为-1,第二个元素的索引为-2,以此类推
Python集合具备确定性、互异性和无序性三个特性。Python要求放入集合中的元素必须是不可变类型,Python中的整型、浮点型、字符串类型和元组属于不可变类型,列表、字典及集合本身都属于可变的数据类型。
确定性:给定一个集合,那么任何一个元素是否在集合中就确定了。
互异性:集合中的元素互不相同。
无序性:集合中的元素没有顺序,顺序不同但元素相同的集合可视为同一集合。
- 列表
2.1 创建列表
Python列表的创建方式非常简单,既可以直接使用中括号“[]”创建,也可以使用内置的list()函数快速创建。
Eg:list_one = [] # 使用[]创建空列表
li_two = list() # 使用list()创建空列表
在Python中,支持通过for…in…语句迭代获取数据的对象就是可迭代对象。目前,我们学习过可迭代的类型有字符串和列表,后续学习的集合、字典、文件也是可迭代类型的对象。使用isinstance()函数可以判断目标是否为可迭代对象,返回True表示为可迭代对象。
Eg:from collections.abc import Iterable
ls = [3,4,5]
print(isinstance(ls, Iterable))
2.2 访问列表元素
列表中的元素可以通过索引或切片这两种方式进行访问,也可以在循环中依次访问。
Eg:list_one = ["Java", "C#", "Python", "PHP"]
print(list_one[1]) #索引
print(list_one[1]) #切片
for li in li_one:
print(li, end=' ') #循环
2.3 添加列表元素
向列表中添加元素是非常常见的一种列表操作,Python提供了append()、extend()和insert()这几个方法。
Eg:list_one = ["Java", "C#", "Python", "PHP"]
list_one.append("C++") #append(在列表末尾添加元素)
list_one.extend([["Android", "IOS",]]) #extend(在列表末尾添加另一个序列的所有元素)
list_one.insert(2,"HTML") #insert(按照索引将元素插入列表的指定位置)
2.4元素排序
列表的排序是将元素按照某种规定进行排列。列表中常用的排序方法有sort()、reverse()、sorted()。
li_one = [6, 2, 5, 3] #示例
list_one.sort() #sort 有序的元素会覆盖原来的列表元素,不产生新列表
li_two = sorted(li_one) #sorted 产生排序后的新列表,排序操作不会对原列表产生影响
li_one.reverse() #reverse 逆置列表,即把原列表中的元素从右至左依次排列存放
2.5 删除列表元素
删除列表元素的常用方式有del语句、remove()方法、pop()方法和clear()方法。
li_one = [6, 2, 5, 3] #示例
del li_one[0] #del 删除列表中指定位置的元素
li_one.remove(3) #remove 移除列表中匹配到的第一个元素
li_one.pop() #pop 移除列表中的某个元素,若未指定具体元素,则移除列表中的最后一个元素
li_one.clear() #clear 清空列表
2.6 列表推导式
列表推导式是符合Python语法规则的复合表达式,它用于以简洁的方式根据已有的列表构建满足特定需求的列表。列表推导式的基本格式如下:
[exp for x in list]
列表推导式还可以结合if判断语句或for循环嵌套,生成更灵活的列表。
- 带有if语句的列表推导式
- for循环嵌套的列表推导式
- 带有if语句与for循环嵌套的列表推导式
- 元组
元组的表现形式为一组包含在圆括号“()”中、由逗号分隔的元素,元组中元素的个数、类型不受限制。除了使用()构建元组外,还可以使用内置函数tuple()构建元组。
t1 = 0 ##使用()构建元组
t2 = tuple ##使用tuple构建元组
当使用圆括号“()”创建元组时,如果元组中只包含一个元素,那么需要在该元素的后面添加逗号,从而保证Python解释器能够识别其为元组类型。
t1 = ('python')
t2 = ('python',)
print(type(t1))
print(type(t2))
输出结果:<class 'str'>
<class 'tuple'>
元组支持以索引和切片方式访问元组的元素,也支持在循环中遍历元组。
tuple_demo = ('p','y','t', 'h', 'o','n') # 示例
tuple_demo[2] #使用索引
tuple_demo[2:5] #使用切片
for i in tuple_demo:
print(i) #遍历元组
- 集合
Python的集合(set)本身是可变类型,但Python要求放入集合中的元素必须是不可变类型。大括号“{}”或内置函数set()均可构建集合。
s1 = {1} #使用{}构建集合
s2 = set{[1,2]} #使用set构建元组
需要注意,使用{}不能创建空集合(不包含元素的{}创建的是字典变量),空集合只能利用set()函数创建。
set_demo1 = {}
set_demo2 = set()
print(type(set_demo1))
print(type(set_demo2))
输出结果:<class 'dict'>
<class 'set'>
集合是可变的,集合中的元素可以动态增加或删除。Python提供了一些内置方法来操作集合,常见内置方法如下:
集合也可以利用推导式创建,集合推导式的格式与列表推导式相似,区别在于集合推导式外侧为大括号“{}”,具体如下:
{exp for x in set if cond}
- 字典
5.1 创建字典
字典的表现形式为一组包含在大括号“{}”中的键值对,每个键值对为一个字典元素,每个元素通过逗号“,”分隔,每对键值通过“:”分隔,除了使用“{}”创建字典还可以使用内置函数dict创建字典。
d1 = {'A':123,12:'Python'} #使用{}构建集合
d2 = dict({'A':'123','B':'135'}) #使用dict构建元组
5.2 字典的访问
d2 = dict({'A':'123','B':'135'}) #使用dict构建元组
d2['A'] #键 ‘123’
d2.get('B') #get() '135'
字典涉及的数据分为键、值和元素(键值对),除了直接利用键访问值外,Python还提供了内置方法keys()、values()和items()。
info = {'name': 'Jack','age':23,'height':185}
info.keys() #获取所有键 dict_keys(['name', 'age', 'height'])
info.values() #获取所有值 dict_values(['Jack', 23, 185])
info.items() #获取所有元素 dict_items([('name', 'Jack'), ('age', 23), ('height', 185)])
5.3 元素的添加和修改
字典支持通过为指定的键赋值或使用update()方法添加或修改元素,下面分别介绍如何添加和修改字典元素。
通过键添加元素:字典变量[键] = 值
使用update()添加元素:dict.update(key=value)
字典支持通过为指定的键赋值或使用update()方法添加或修改元素,下面分别介绍如何添加和修改字典元素。
add_dict= {'name': 'Jack','age':23,'height':185}
add_dict['sco'] = 98 #通过键添加
add_dict.update(sco=98) #使用update方法添加
修改字典元素的本质是通过键获取值,再重新对元素进行赋值。修改元素的操作与添加元素的操作相同。
modify_dict = {'stu1': '小明', 'stu2': '小刚', 'stu3': '小兰'}
modify_dict['stu3'] = '刘婷' #通过键修改
modify_dict.update(stu2='张强') #使用updat方法修改
5.4 字典元素的删除
Python支持通过pop()、popitem()和clear()方法删除字典中的元素
pop():根据指定键值删除字典中的指定元素
popitem():随机删除字典中的元素
clear():清空字典中的元素
字典推导式外侧为大括号“{}”,且内部需包含键和值两部分,具体格式如下
{new_key:new_value for key,value in dict.items()}
利用字典推导式可快速交换字典中的键和值,示例如下:
old_dict = {'name': 'Jack','age':23,'height':185}
new_dict = {value:key for key,value in old_dict.items()}
print(new_dict)
输出结果:{'Jack': 'name', 23: 'age', 185: 'height'}
- 组合数据类型与运算符
Python中针对数字类型的运算符对组合数据类型同样适用,包括+、*、in、not in。
字符串、列表和元组使用“ + ”运算符,会对数据进行拼接
字符串、列表和元组使用“ * ”运算符,会对数据进行整数倍拼接
“in”“not in”运算符称为成员运算符,用于判断某个元素是否属于某个变量
第六章 函数
1.函数概述
函数是组织好的、实现单一功能或相关联功能的代码段。我们可以将函数视为一段有名字的代码,这类代码可以在需要的地方以“函数名()”的形式调用。
格式:print()
input()
函数式编程具有以下优点:
将程序模块化,既减少了冗余代码,又让程序结构更为清晰
提高开发人员的编程效率
方便后期的维护与扩展
2.函数的定义与调用
2.1定义函数
前面使用的print()函数和input()都是Python的内置函数,这些函数由Python定义。开发人员也可以根据自己的需求定义函数,Python中使用关键字def来定义函数,其语法格式如下:
def 函数名([参数列表]):
["""文档字符串"""]
函数体
[return语句]
2.2调用函数
函数在定义完成后不会立刻执行,直到被程序调用时才会执行。
语法格式如下: 函数名([参数列表]):
函数内部也可以调用其他函数,这被称为函数的嵌套调用。
def add_modify(a, b):
result = a + b
add()
print(result)
add_modify(10, 20)
函数在定义时可以在其内部嵌套定义另外一个函数,此时嵌套的函数称为外层函数,被嵌套的函数称为内层函数。
def add_modify(a, b):
result = a + b
print(result)
def test():
print("我是内层函数")
add_modify(10, 20)
3.函数参数的传递
3.1位置参数的传递
我们通常将定义函数时设置的参数称为形式参数(简称为形参),将调用函数时传入的参数称为实际参数(简称为实参)。函数的参数传递是指将实际参数传递给形式参数的过程。
函数参数的传递可以分为位置参数传递、关键字参数传递、默认参数传递、参数的打包与解包以及混合传递。
函数在被调用时会将实参按照相应的位置依次传递给形参,也就是说将第一个实参传递给第一个形参,将第二个实参传递给第二个形参,以此类推。
def get_max(a, b):
if a > b:
print(a,"是较大的值!")
else:
print(b,"是较大的值!")
get_max(8, 5)
3.2 关键字参数的传递
关键字参数的传递是通过“形参=实参”的格式将实参与形参相关联,将实参按照相应的关键字传递给形参。
def connect(ip, port):
print(f"设备{ip}:{port}连接!")
connect(ip="127.0.0.1", port=8080)
无论实参采用位置参数的方式传递,还是关键字参数的方式传递,每个形参都是有名称的,怎么区分用哪种方式传递呢?
符号“/”
Python在3.8版本中新增了仅限位置形参的语法,使用符号“/”来限定部分形参只接收采用位置传递方式的实参。
def func(a, b, /, c):
print(a, b, c)
3.3 默认参数的传递
函数在定义时可以指定形参的默认值,如此在被调用时可以选择是否给带有默认值的形参传值,若没有给带有默认值的形参传值,则直接使用该形参的默认值。
def connect(ip, port=8080):
print(f"设备{ip}:{port}连接!")
connect(ip="127.0.0.1")
connect(ip="127.0.0.1", port=3306)
输出结果:设备127.0.0.1:8080连接!
设备127.0.0.1:3306连接!
3.4参数的打包于解包
3.4.1 打包
如果函数在定义时无法确定需要接收多少个数据,那么可以在定义函数时为形参添加“*”或“**”:
“*” —— 接收以元组形式打包的多个值
“**”—— 接收以字典形式打包的多个值
“*”
def test(*args):
print(args)
test(11,22,33,44,55)
输出结果:(11, 22, 33, 44, 55)
“**”
def test(**kwargs):
print(kwargs)
test(a=11, b=22, c=33, d=44, e=55)
输出结果:{'a': 11, 'b': 22, 'c': 33, 'd': 44, 'e': 55}
虽然函数中添加“*”或“**”的形参可以是符合命名规范的任意名称,但这里建议使用*args和**kwargs。
若函数没有接收到任何数据,参数*args和**kwargs为空,即它们为空元组或空字典。
3.4.2 解包
实参是元组 → 可以使用“*”拆分成多个值 → 按位置参数传给形参
实参是字典 → 可以使用“**” 拆分成多个键值对 → 按关键字参数传给形参
def test(a, b, c, d, e):
print(a, b, c, d, e)
nums = (11, 22, 33, 44, 55)
test(*nums)
输出结果:{'a': 11, 'b': 22, 'c': 311 22 33 44 553, 'd': 44, 'e': 55}
3.5 混合传递
前面介绍的参数传递的方式在定义函数或调用函数时可以混合使用,但是需要遵循一定的规则,具体规则如下。
优先按位置参数传递的方式。
然后按关键字参数传递的方式。
之后按默认参数传递的方式。
最后按打包传递的方式。
在定义函数时:
带有默认值的参数必须位于普通参数之后。
带有“*”标识的参数必须位于带有默认值的参数之后。
带有“**”标识的参数必须位于带有“*”标识的参数之后。
def test(a, b, c=33, *args, **kwargs):
print(a, b, c, args, kwargs)
test(1, 2)
test(1, 2, 3)
test(1, 2, 3, 4)
test(1, 2, 3, 4, e=5)
输出结果:1 2 33 () {}
1 2 3 () {}
1 2 3 (4,) {}
1 2 3 (4,) {'e': 5}
5,函数的返回值
函数中的return语句会在函数结束时将数据返回给程序,同时让程序回到函数被调用的位置继续执行。
def filter_sensitive_words(words):
if "山寨" in words:
new_words = words.replace("山寨", "**")
return new_words
result = filter_sensitive_words("这个手机是山寨版吧!")
print(result)
输出结果:这个手机是**版吧!
如果函数使用return语句返回了多个值,那么这些值将被保存到元组中。
def move(x, y, step):
nx = x + step
ny = y - step
return nx, ny # 使用return语句返回多个值
result = move(100, 100, 60)
print(result)
输出结果:(160, 40)
5,变量作用域
变量并非在程序的任意位置都可以被访问,其访问权限取决于变量定义的位置,其所处的有效范围称为变量的作用域。
根据作用域的不同,变量可以划分为局部变量和全局变量。
5.1 局部变量和全局变量
函数内部定义的变量,只能在函数内部被使用
函数执行结束之后局部变量会被释放,此时无法再进行访问。
5.1.1 局部变量
def test_one():
number = 10 # 局部变量
print(number) # 函数内部访问局部变量
test_one()
print(number) # 函数外部访问局部变量
不同函数内部可以包含同名的局部变量,这些局部变量的关系类似于不同目录下同名文件的关系,它们相互独立,互不影响。
def test_one():
number = 10
print(number) # 访问test_one()函数的局部变量number
def test_two():
number = 20
print(number) # 访问test_two()函数的局部变量number
test_one()
test_two()
输出结果:10
20
5.2.2 全局变量
全局变量可以在整个程序的范围内起作用,它不会受到函数范围的影响。
number = 10 # 全局变量
def test_one():
print(number) # 函数内部访问全局变量
test_one()
print(number)
输出结果:10
10
全局变量在函数内部只能被访问,而无法直接修改。
# 定义全局变量
number = 10
def test_one():
print(number)
number += 1
test_one()
print(number)
这是因为函数内部的变量number视为局部变量,而在执行“number+=1”这行代码之前并未声明过局部变量number。
5.2 global和nonlocal关键字
函数内部无法直接修改全局变量或在嵌套函数的外层函数声明的变量,但可以使用global或nonlocal关键字修饰变量以间接修改以上变量。
5.2.1 global关键字
使用global关键字可以将局部变量声明为全局变量,其使用方法如下:
global 变量
number = 10 # 定义全局变量
def test_one():
global number # 使用global声明变量number为全局变量
number += 1
print(number)
test_one()
print(number)
5.2.2 nonlocal关键字
使用nonlocal关键字可以在局部作用域中修改嵌套作用域中定义的变量,其使用方法如下:
nonlocal 变量
def test():
number = 10
def test_in():
nonlocal number
number = 20
test_in()
print(number)
test()
6 特殊形式的函数
1.递归函数
函数在定义时可以直接或间接地调用其他函数。若函数内部调用了自身,则这个函数被称为递归函数。
递归函数在定义时需要满足两个基本条件:一个是递归公式,另一个是边界条件。其中:
递归公式是求解原问题或相似的子问题的结构;
边界条件是最小化的子问题,也是递归终止的条件。
递归函数的执行可以分为以下两个阶段:
1.递推:递归本次的执行都基于上一次的运算结果。
2.回溯:遇到终止条件时,则沿着递推往回一级一级地把值返回来。
格式:def函数名([参数列表]):
if 边界条件:
rerun 结果
else:
return 递归公式
2.匿名函数
匿名函数是一类无需定义标识符的函数,它与普通函数一样可以在程序的任何位置使用。Python中使用lambda关键字定义匿名函数,它的语法格式如下:
lambda <形式参数列表> :<表达式>
匿名函数与普通函数的主要区别如下:
普通函数在定义时有名称,而匿名函数没有名称;
普通函数的函数体中包含有多条语句,而匿名函数的函数体只能是一个表达式;
普通函数可以实现比较复杂的功能,而匿名函数可实现的功能比较简单;
普通函数能被其他程序使用,而匿名函数不能被其他程序使用。
定义好的匿名函数不能直接使用,最好使用一个变量保存它,以便后期可以随时使用这个函数。
# 定义匿名函数,并将它返回的函数对象赋值给变量temp
temp = lambda x : pow(x, 2)
temp(10)
第七章 文件与数据的格式化
1,文件概述
文件标识:文件标识的意义:找到计算机中唯一确定的文件。
文件标识的组成:文件路径、文件名主干、文件扩展名。
操作系统以文件为单位对数据进行管理。
文件类型:根据数据的逻辑存储结构,人们将计算机中的文件分为文本文件和二进制文件。
文本文件:专门存储文本字符数据。
二进制文件:不能直接使用文字处理程序正常读写,必须先了解其结构和序列化规则,再设计正确的反序列化规则,才能正确获取文件信息。
- 二进制文件和文本文件这两种类型的划分基于数据逻辑存储结构而非物理存储结构,计算机中的数据在物理层面都以二进制形式存储。
标准文件:Python的sys模块中定义了3个标准文件,分别为:
stdin(标准输入文件)。标准输入文件对应输入设备,如键盘。
stdout(标准输出文件)。
stderr(标准错误文件)。标准输出文件和标准错误文件对应输出设备,如显示器。
Eg:import sys
file = sys.stdout
file.write("hello")
2.文件的基础操作
文件的打开、关闭与读写是文件的基础操作,任何更复杂的文件操作都离不开这些操作。
2.1 打开文件
内置函数open()用于打开文件,该方法的声明如下:
open(file, mode='r', buffering=-1)
打开模式 | 名称 | 描述 | |
r/rb | 只读模式 | 以只读的形式打开文本文件/二进制文件,若文件不存在或无法找到,文件打开失败 | |
w/wb | 只写模式 | 以只写的形式打开文本文件/二进制文件,若文件已存在,则重写文件,否则创建新文件 | |
a/ab | 追加模式 | 以只写的形式打开文本文件/二进制文件,只允许在该文件末尾追加数据,若文件不存在,则创建新文件 | |
r+/rb+ | 读取(更新)模式 | 以读/写的形式打开文本文件/二进制文件,若文件不存在,文件打开失败 |
|
w+/wb+ | 写入(更新)模式 | 以读/写的形式打开文本文件/二进制文件,若文件已存在,则重写文件 | |
a+/ab+ | 追加(更新)模式 | 以读/写的形式打开文本/二进制文件,只允许在文件末尾添加数据,若文件不存在,则创建新文件 |
2.1文件的打开与关闭
内置函数open()用于打开文件,该方法的声明如下:
open(file, mode='r', buffering=-1)
2.关闭文件
Python可通过close()方法关闭文件,也可以使用with语句实现文件的自动关闭。
2.文件的读写
Python可通过close()方法关闭文件,也可以使用with语句实现文件的自动关闭。Python可通过close()方法关闭文件,也可以使用with语句实现文件的自动关闭。
2.2 读取文件——read(方法)
read()方法可以从指定文件中读取指定字节的数据,其语法格式如下:
read(n=-1)
with open('file.txt', mode='r') as f:
print(f.read(2)) # 读取两个字节的数据
print(f.read())
2.3 readline()文件
readline()方法可以从指定文件中读取一行数据,其语法格式如下:
readline()
with open('file.txt', mode='r', encoding='utf-8') as f:
print(f.readline())
print(f.readline())
readlines()方法可以一次读取文件中的所有数据,若读取成功,该方法会返回一个列表,文件中的每一行对应列表中的一个元素。语法格式如下:
readlines(hint=-1)
with open('file.txt', mode='r', encoding='utf-8') as f:
print(f.readlines())
2.写文件
2.1 write
write()方法可以将指定字符串写入文件,其语法格式如下:
write(data)
以上格式中的参数data表示要写入文件的数据,若数据写入成功,write()方法会返回本次写入文件的数据的字节数。
string = "Here we are all, by day; by night." # 字符串
with open('write_file.txt', mode='w', encoding='utf-8') as f:
size = f.write(string) # 写入字符串
print(size)
文本文件支持多种编码方式,不同编码方式下字符与字节的对应关系不同,常见的编码方式以及字符与字节的对应关系如表所示。
编码方式 | 语言 | 字符数 | 字节数 |
ASCII | 中文 | 1 | 2 |
英文 | 1 | 1 | |
UTF-8 | 中文 | 1 | 3 |
英文 | 1 | 1 | |
Unicode | 中文 | 1 | 2 |
英文 | 1 | 2 | |
GBK | 中文 | 1 | 2 |
英文 | 1 | 1 |
Tell
tell()方法用于获取文件当前的读写位置,以操作文件file.txt为例,tell()的用法如下:
with open('file.txt') as f:
print(f.tell()) # 获取文件读写位置
print(f.read(5)) # 利用read()方法移动文件读写位置
print(f.tell()) # 再次获取文件读写位置
seek
Python提供了seek()方法,使用该方法可控制文件的读写位置,实现文件的随机读写。seek()方法的语法格式如下:
seek(offset, from)
offset:表示偏移量,即读写位置需要移动的字节数。
from:用于指定文件的读写位置,该参数的取值为0、1、2。
Python提供了seek()方法,使用该方法可控制文件的读写位置,实现文件的随机读写。seek()方法的语法格式如下:
seek(offset, from)
with open('file.txt') as f:
print(f.tell()) # 获取文件读写位置
print(f.read(5)) # 利用read()方法移动文件读写位置
print(f.tell()) # 再次获取文件读写位置
需要注意的是,在Python3中,若打开的是文本文件,那么seek()方法只允许相对于文件开头移动文件位置,若在参数from值为1、2的情况下对文本文件进行位移操作,将会产生错误。
with open('file.txt') as f:
f.seek(5,0) # 相对文件开头移动5字节
f.seek(3,1)
若要相对当前读写位置或文件末尾进行位移操作,需以二进制形式
with open('file.txt','rb') as f:
f.seek(5,0)
f.seek(3,1)
3.文件与目录的管理
管理文件与目录
- 删除文件——os.remove(文件名)
- 文件重命名——os.rename(原文件名,新文件名)
- 创建/删除目录——os.mkdir(目录名)/os.rmdir(目录名)
- 获取当前目录——os.getcwd()
- 更改默认目录——os.chdir(路径名)
- 获取目录列表——os.listdir(目录/路径)
4.数据维度域数据格式化
一二维数据的存储与读写
1.数据存储
一维数据呈线性排列,一般用特殊字符分隔,例如:
- 使用空格分隔:成都 杭州 重庆 武汉 苏州 西安 天津
- 使用逗号分隔:成都,杭州,重庆,武汉,苏州,西安,天津
- 使用&分隔:成都&杭州&重庆&武汉&苏州&西安&天津
一维数据的存储需要注意以下几点:
- 同一文件或同组文件一般使用同一分隔符分隔。
- 分隔数据的分隔符不应出现在数据中。
- 分隔符为英文半角符号,一般不使用中文符号作为分隔符。
- 二维数据可视为多条一维数据的集合,当二维数据只有一个元素时,这个二维数据就是一维数据。
CSV(Commae-Separeted Values,逗号分隔值)是国际上通用的一二维数据存储
CSV格式规范:
- 以纯文本形式存储表格数据
- 文件的每一行对应表格中的一条数据记录
- 每条记录由一个或多个字段组成
- 字段之间使用逗号(英文、半角)分隔
- CSV也称字符分隔值,具体示例如下:
- 姓名,语文,数学,英语,理综
- 刘婧,124,137,145,260
- 张华,116,143,139,263
- 邢昭林,120,130,148,255
- 鞠依依,115,145,131,240
- 黄丽萍,123,108,121,235
- 赵越,132,100,112,210
2.数据读取
- Windows平台中CSV文件的后缀名为.csv,可通过Office Excel或记事本打开
- Python在程序中读取.csv文件后会以二维列表形式存储其中内容
- csv_file = open('score.csv') lines = [] for line in csv_file: line = line.replace('\n','') lines.append(line.split(',')) print(lines) csv_file.close()
3.数据写入
将一、二维数据写入文件中,即按照数据的组织形式,在文件中添加新的数据。
多维数据的格式化
为了直观地表示多维数据,也为了便于组织和操作,三维及以上的多维数据统一采用键值对的形式进行格式化。
网络平台上传递的数据大多是高维数据,JSON是网络中常见的高维数据格式。JSON格式的数据遵循以下语法规则:
- 数据存储在键值对(key:value)中,例如“姓名”: “张华”。
- 数据的字段由逗号分隔,例如“姓名”: “张华”, “语文”: “116”。
- 一个花括号保存一个JSON对象,例如{“姓名”: “张华”, “语文”: “116”}。
- 一个方括号保存一个数组,例如[{“姓名”: “张华”, “语文”: “116”}]。
- “高三二班考试成绩”:[ {“姓名”: “陈诚”, “语文”: “124”, “数学”: “127”, “英语”: “145”, “理综”: “259” }; {“姓名”: “黄思”, “语文”: “116”, “数学”: “143”, “英语”: “119”, “理综”: “273” }; …… ]
- <高三二班考试成绩> <姓名>陈诚</姓名><语文>124</语文><数学>127<数学/><英语>145<英语/><理综>259<理综/> <姓名>黄思</姓名><语文>116</语文><数学>143<数学/><英语>119<英语/><理综>273<理综/> …… </高三二班考试成绩>
JSON模块——json
利用json模块的dumps()函数和loads()函数可以实现Python对象和JSON数据之间的转换,这两个函数的具体功能如表所示。
函数 | 功能 |
dumps() | 对Python对象进行转码,将其转化为JSON字符串 |
loads() | 将JSON字符串解析为Python对象 |
Dumps()函数
使用dumps()函数对Python对象进行转码。
Loads()函数