目录
1.字典;
字典是一种存储键值对的结构;
键值对包括键(key)与值(value),含义在于在键与值之间建立一种映射关系;
在Python的字典中,可以同时包含很多个键值对,同时要求这些键值对不能重复。
1.1 创建字典
# 方法1:直接创建
a = {}
print(type(a))
# 方法2:使用dict创建
b = dict()
print(type(b))
# 方法3:在创建时设置初始值
c = {'id': 1, 'name': 'zhangsan'}
print(c)
在字典c中包含了两个键值对,用逗号分开:
① 'id': 1 key是'id' value是1
② 'name': 'zhangsan' key是'name' value是'zhangsan'
注:① 一个字典中各种key的类型不一定都相同,各种value的类型也可以多种;
② 字典对于key的类型是由约束的,但是对于value的类型没有约束;
③ 建议字典采取多行书写:
c = {
'id': 1,
'name': 'zhangsan'
}
④ 最后一组键值对后的逗号可有可无;
1.2 查找key
1.2.1 使用in判断key是否存在
a = {
'name': 'zhangsan',
'id': 1
}
print('id' in a)
print('ClassId' in a)
输出结果为:
注意:(1)in只判断key 是否存在,和value无关:当运行print('zhangsan' in a)时会输出False;
(2)同理列表,not in也可用于此处查找key
1.2.2 使用[ ]来根据key获取到value
a = {
'name': 'zhangsan',
'id': 1
}
print(a['id'])
print(a['name'])
输出结果为:
注:[ ]类似于数组或顺序表取下标,in使用了哈希表,[ ]是相对in更高效的操作
1.3 新增 / 修改元素
a ={
'id': 1,
'name': 'zhangsan'
}
a['score'] = 90
print(a)
a['score'] = 100
print(a)
输出结果为:
当目标key不存在时,[ ]操作是新增键值对,当目标key已存在时,[ ]操作是对应key修改value;
1.4 删除元素
使用pop方法根据key删除键值对:
a = {'id': 1,
'name': 'zhangsan',
'score': 100
}
print(a)
a.pop('name')
print(a)
输出结果为:
1.5 遍历字典元素
a = {
'id': 1,
'name': 'zhangsan',
'score': 90
}
for key in a:
print(key, a[key])
输出结果为:
注:在C++、Java中,哈希表内键值对的存储顺序是无序的,但是Python做了特殊处理,能保证遍历出来的顺序与插入的顺序一致;
1.6 取出所有key和value
python中可以使用keys方法values方法 items方法来获取所有的key、value、键值对:
a = {
'id': 1,
'name': 'zhangsan',
'score': 90
}
print(a.keys())
print(a.values())
print(a.items())
输出结果为:
注:① keys返回的结果是一个自定义的dict_类型,使用的时候可以将其视作一个字典;
② items是一个类似于列表一样的结构,里面每个元素又是一个元组;
③ 也可以借用该种方法进行字典遍历:
a = {
'id': 1,
'name': 'zhangsan',
'score': 90
}
for key, value in a.items():
print(key, value)
1.7 合法的key类型
字典本质上是一个哈希表,哈希表的key的要求是可哈希的,也就是可以计算出一个哈希值。
一部分数据类型是可以哈希的:
print(hash(0)) # 整数
print(hash(3.14)) # 浮点数
print(hash('hello')) # 字符串
print(hash(True)) # 布尔值
print(hash((1, 2, 3))) # 元组
输出结果为:
一部分数据类型不能哈希:
(1)列表:
print(hash([1, 2, 3]))
(2)字典:
print(hash({'num': 1}))
注:可以认为一个不可变的对象一般就是可哈希的,可变的对象一般就是不可哈希的。
2.文件
硬盘上的数据就是以文件的形式来组织的,文件都是保存在硬盘上的。
即使是文件,但其存储文件的方式差异也是很大的,重点研究文本文件:
2.1 文件路径
将一层一层目录构成的字符串称为“文件的路径”;
如:
C:\Users\Administrator\Downloads\pycharm-community-2022.3.1.exe就是pycharm的文件路径。
(目录名之间使用反斜杠来分割正斜杠也可,Linux、Mac操作系统下为正斜杠)
获取到文件路径后,就可以知道该文件在硬盘上的详细位置,也就可以知道该文件的存储内容了。
2.2 文件操作
2.2.1 打开文件
open('C:\Users\Administrator\Downloads\test.txt','r')
文件路径+打开方式:
打开方式:r表示read:按照读方式打开,w表示write:按照写方式打开,a表示append:也是写方式打开,是将内容写到原有文件内容的末尾;
open函数的返回值是一个文件对象,故而需要创建一个文件对象来接收:
f = open('C:\Users\Administrator\Downloads\test.txt','r')
文件内容是在硬盘上的,而此处的文件对象则是一个内存上的变量,后续读写文件操作都是针对该文件对象来进行操作的。
计算机中,也把这样的远程操控的“遥控器”称为句柄(handler)
(1)当目标文件存在时,试运行:(已在对应路径下创建相关文件test.txt)
f = open('d:/Project2/test.txt', 'r')
print(f)
print(type(f))
输出结果为:
其中类型是python内部给文件对象起的名字,仅作文件对象理解即可;
(2)当目标文件不存在时,试运行:(未在对应路径下创建相关文件text1.txt)
f = open('d:/Project2/test1.txt', 'r')
print(f)
print(type(f))
当文件不存在时尝试按照读方式打开就会抛出“文件没找到”异常;
2.2.2 关闭文件
文件打开使用完之后一定要关闭:
打开文件其实是在申请系统资源,不再使用文件的时候,资源就应该及时释放,否则就可能造成文件资源泄漏,进一步导致其他部分的代码无法顺利打开文件了。
正是因为一个系统的资源是有限的,因此一个程序能打开的文件个数也是有上限的。
f = open('d:/Project2/test.txt', 'r')
print(f)
print(type(f))
f.close()
2.2.3 写文件
(1)直接写:
f = open("d:/Project2/test.txt", 'w')
f.write('hello')
f.close()
根据文件路径打开文件:
注:① 此处写文件必须使用w方式打开,如果用r方式打开,则会抛出异常:
② w方式打开会清空掉文件原有内容:
f = open("d:/Project2/test.txt", 'w')
f.write('hello')
f.close()
f = open("d:/Project2/test.txt", 'w')
f.close()
根据文件路径打开文件:
(2)追加写:
a方式打开文件不会清空文件原有内容,写的内容会追加在原有文件内容的末尾:
f = open("d:/Project2/test.txt", 'w')
f.write('hello' ' ')
f.close()
f = open("d:/Project2/test.txt", 'a')
f.write('world')
f.close()
根据文件路径打开文件:
注:如果文件对象已经被关闭了,那么意味着系统中和该文件相关的内存资源已经释放了,强行去写,就会出异常:
f = open("d:/Project2/text.txt", 'w')
f.close()
f.write('!!!')
报错如下:
(I / O操作针对了一个已关闭的文件)
2.2.4 读文件
f = open("d:/Project2/text1.txt", 'w')
f.write("床前明月光\n")
f.close()
f = open("d:/Project2/text1.txt", 'a')
f.write("疑是地上霜\n")
f.write("举头望明月\n")
f.write("低头思故乡\n")
f.close()
# 1.使用read来读取文件内容,指定读几个字符
f = open("d:/Project2/text1.txt", 'r', encoding='gbk')
# f = open("d:/Project2/text1.txt", 'r', encoding='ANSI')
result = f.read(2) # 读前两个字符
print(result)
f.close()
# 2.按行读取文件内容
f = open("d:/Project2/text1.txt", 'r', encoding='gbk')
for line in f:
print(f"line={line}")
f.close()
# 3.使用readlines方法直接把整个文件所有内容都读取出来,按照行组织到一个列表里
f = open("d:/Project2/text1.txt", 'r', encoding='gbk')
lines = f.readlines()
print(lines)
f.close()
输出结果为:
注:① encoding='gbk'与encoding='ANSI'都是在指定编码方式,打开对应文件可以在右下角处看到当前编码方式:
此处也可指定使用广泛使用的gbk编码;
② 采用按行读取时每一行输出之间还多出了一个空行是因为文件内容一行文字后就有一个换行符\n,使用print打印又会自动增加一个换行符,可以给print再设定一个参数修改print自动添加换行行为:
f = open("d:/Project2/text1.txt", 'r', encoding='gbk')
for line in f:
print(f"line={line}", end='')
f.close()
输出结果即为
end参数表示每次打印完之后在末尾增加的内容,默认是换行符,修改成空字符串表示不增加任何东西即可。
2.3 上下文管理器
在我们编写代码中:
def function():
f = open("d:/Project2/text1.txt", 'r', encoding='gbk')
# 文件操作
f.close()
如果在文件打开与关闭的操作之间有条件判定、函数返回、抛出异常等等,就会无法执行文件关闭 ,为了确保文件的正常关闭,python中设定了上下文管理器:
def function():
with open("d:/Project2/text1.txt", 'r', encoding='gbk') as f:
# 进行文件处理逻辑
此处的f仍然是open的返回值,但是f已经在with的监控之中了,当with对应的代码块执行结束,就会自动的执行f.close()操作。
3.使用库
python中通过模块来体现库,库的使用大大降低了程序员的学习成本,并提高了程序的开发效率;
按照库的来源可以分为两大类:标准库与第三方库:
标准库:Python自带的库,只要安装了python就可以使用:
官方文档链接如下:
https://docs.python.org/3.10/library/index.html
第三方库:其他人实现的库,若要使用需要额外安装。
3.1 标准库
3.1.1 代码示例:日期计算
代码1:
# 导入模块
import datetime
# 构造datetime变量
date1 = datetime.datetime(year=2012, month=2, day=14)
date2 = datetime.datetime(year=2016, month=2, day=3)
print(date2 - date1)
代码2:
from datetime import datetime
date1 = datetime(year=2012, month=2, day=14)
date2 = datetime(year=2016, month=2, day=3)
print(date2-date1)
代码3:
import datetime as dt
date1 = dt.datetime(year=2012, month=2, day=14)
date2 = dt.datetime(year=2016, month=2, day=3)
print(date2-date1)
输出结果为:
3.1.2 代码示例:字符串操作
(1)翻转单词顺序
解题思路为:
① 针对上述字符串,使用空格进行切分:
字符串split方法,可以指定分割符,把字符串分成多个部分,放到一个list中;
② 针对刚才的切分结果列表进行逆序;
③ join组合逆序后列表;
题解:
def reverse_words(s: str):
tokens = s.split(' ')
tokens.reverse()
return ' '.join(tokens)
print(reverse_words("I am a student."))
运行示例:
(2)旋转字符串
解题思路为:
在s+s中寻找是否有对应字符串;
题解:
def rotate_string(s, goal):
if len(s) != len(goal):
return False
return goal in (s+s)
print(rotate_string("abcde", "cdeab"))
print(rotate_string("abcde", "edcba"))
运行示例:
(3)统计是给定字符串前缀的字符串数目
解题思路:
遍历数组words,取出每个字符串判定s是否是以这个字符串开头的即可;
题解:
def count_prefixes(words:list, s:str):
count = 0
for word in words:
if s.startswith(word):
count += 1
return count
print(count_prefixes(['a', 'b', 'c', 'ab', 'bc', 'abc'], 'abc'))
print(count_prefixes(['a', 'a'], 'aa'))
运行示例:
3.1.3 文件查找工具
指定一个待搜索路径,同时指定一个待搜索的关键字,在待搜索路径中查找是否文件名中包含这个关键字:递归查找遇到子目录就进目录里进行查找,需要使用到os.walk来遍历操作系统的目录。
# 文件查找工具
# 输入要查找的路径,输入要搜索的文件名
import os
inputPath = input("请输入要搜索的路径:")
pattern = input("请输入要搜索的关键字:")
for dirpath, dirnames, filenames in os.walk(inputPath):
# 第一个参数为:遍历到当前位置对应的路径是什么
# 第二个参数为:当前目录下都有哪些目录(是一个列表,可以包含多个目录名)
# 第三个参数为:当前目录下都有哪些文件名(是一个列表,可以包含多个文件名)
# os.walk每次调用都能自动地针对子目录进行递归操作
# print("--------------------")
# print(f"dirpath = {dirpath}")
# print(f"dirnames = {dirnames}")
# for name in dirnames:
# print(name)
# print(f"filenames = {filenames}")
# for name in filenames:
# print(name)
for f in filenames:
if pattern in f:
print(f"{dirpath}/{f}")
文件文档存储关系为:
运行示例为:
3.2 第三方库
第三方库就是别人已经实现好各种功能的库,我们可以直接调取使用。
当我们确定了该使用哪个第三方库后,就可以使用pip来安装第三方库了:
3.2.1 使用pip
第三方库有很多,是不同的人不同的组织实现的,为了方便大家整理,Python官方提供了一个网站PYPI https://pypi.org/ 来收集第三方库,同时提供了一个pip工具,就能直接从pypi上下载需要的第三方库了。pip是Python内置的包管理器,类似于手机的app store。
安装python时已经自动地安装好了pip,直接使用即可。
pip是一个命令行程序,使用方法如下:
第一步:
在pycharm中点击Terminal:
或开始键 + r + 输入cmd:
第二步(以在pycharm中操作为例):
输入pip,就会出现pip的大量操作选项提示,如果显示pip不是内部或外部命令,也不是可运行程序或批处理文件之类的提示,则是安装python时没有勾选Add Python 3.10 to PATH,可以手动将pip所在路径加入到PATH环境变量中(参考https://www.jianshu.com/p/1de0acf7185d),或是卸载重新安装python。
第三步:
使用 pip install [库名] 命令,安装第三方库。
安装成功后即可使用import导入相关模块,即可进行使用。
3.2.2 代码示例
(1)生成二维码:
二维码的本质就是一段字符串我们可以把任意的字符串制作成一个二维码图片。生活中使用的二维码更多的是一个URL(网址)。
① 通过搜索引擎,确定使用哪个库:
确定qrcode库;
② PYPI官方网站搜索qrcode:
将 pip install qrcode[pil] 复制粘贴至输入处即可开始安装;
③ 安装完成后,在官网查看使用方法:
试编写如下代码:
import qrcode
img = qrcode.make("hello world")
img.save('qrcode.png')
运行后双击左侧栏qrcode.png即可获得二维码,使用扫码app扫码后可显示:
此种方法可以用于博客文章等等附于纸质简历后便于面试官了解。
(2)操作excel
不再详细展示具体方法,安装命令为:pip install xlrd==1.2.0
读取excel可以使用xlrd模块,修改excel可以使用xlwt模块,此处以xlrd为例演示excel的基本操作:
在d:/Project3路径下创建一个test.xlsx的表格,在Sheet1标签页下填充部分内容,表格内容为:
试编写代码求班级号为100的同学的平均分数:
# 操作excel
import xlrd
# 1. 先打开xlsx文件
xlsx = xlrd.open_workbook("d:/Project3/test.xlsx")
# 2. 获取到指定标签页(Sheet)
table = xlsx.sheet_by_index(0)
# 3. 获取表格行数
nrows = table.nrows
# 4. 进行循环统计操作
total = 0 # 总分数
count = 0 # 总人数
for i in range(1, nrows):
# 拿到当前同学的班级号
classId = table.cell_value(i, 1)
# 两个参数分别对应行数和列数,均从0开始,类似二维数组
if classId == 100:
total += table.cell_value(i, 2)
count += 1
print(f"平均成绩为:{total/count}")