Python学习Day11
字典
Python中也存在字典,Python的字典把这个字(或单词)成为“键(key)”,其对应的含义称为“值(value)”。
普通的索引查找方式:
>>> brand = ["物理","化学","生物"]
>>> translate = ["Physcic","Chemistry","Biology"]
>>> print("生物的英文是: %s" % translate[brand.index("生物")])
生物的英文是: Biology
缺点:用起来别扭,而且效率不高
字典的标志性符号用大括号{}表示,字典不是序列类型,字典是映射类型
字典的使用:
>>> dict1 = {"物理":"Physcic","化学":"Physcic","生物":"Biology"}
>>> print("生物的英文是:",dict1["生物"])
生物的英文是: Biology
>>> #其中物理化学生物是字典中的键,而它们对应的英文是字典中的值,它们之间用冒号隔开
字典的键必须是独一无二的,但值则不必。值可以取任何数据类型,但必须是不可变的,如字符串、数或者元组
字典的创建和访问:
>>> dict2 = {1:'one',2:'two',3:'three'}
>>> dict2[2]
'two'
>>> #创建一个空字典
>>> dict3 = {}
>>> dict3
{}
>>> #也可以使用dict()内置函数来创建字典
>>> dict4 = dict((('one',1),('two',2),('three',3)))
>>> dict4
{'one': 1, 'two': 2, 'three': 3}
>>> #还可以通过具有映射关系的参数来创建字典
>>> dict4 = dict(one = 1,two = 2,three = 3)
>>> dict4
{'one': 1, 'two': 2, 'three': 3}
>>> #直接给键赋值
>>> dict4
{'one': 1, 'two': 2, 'three': 3}
>>> dict4['four'] = 4
>>> dict4
{'one': 1, 'two': 2, 'three': 3, 'four': 4}
>>> dict4['one'] = 0
>>> dict4
{'one': 0, 'two': 2, 'three': 3, 'four': 4}
字典内置的各种方法
fromkeys(seq[,value])
用于创建并返回一个新的字典,它有两个参数;第一个参数是字典的键;第二个参数是可选的,是传入键对应的值,如果不提供,那么默认是None。
>>> dict1 = {}
>>> dict1.fromkeys((1,2,3))
{1: None, 2: None, 3: None}
>>> dict1.fromkeys((1,2,3),'Number')
{1: 'Number', 2: 'Number', 3: 'Number'}
>>> dict1.fromkeys((1,2,3),('one','two','three'))
{1: ('one', 'two', 'three'), 2: ('one', 'two', 'three'), 3: ('one', 'two', 'three')}
>>> #如果试图单独修改字典中1和3的值,那么Python会重新创造一个新的字典
>>> dict1.fromkeys((1,3),'number')
{1: 'number', 3: 'number'}
访问字典的方法
- keys():用于返回字典中的键
- values():用于返回字典中所有的值
- items():返回字典中所有的键值
- get(key,[,default]):但键不存在时,get()方法并不会报错,只是默默地返回一个None,表示啥都没找到
>>> dict1 = dict1.fromkeys(range(5),'关注')
>>> dict1
{0: '关注', 1: '关注', 2: '关注', 3: '关注', 4: '关注'}
>>> for eachKey in dict1.keys():
print(eachKey)
0
1
2
3
4
>>> for eachValue in dict1.values():
print(eachValue)
关注
关注
关注
关注
关注
>>> for eachItem in dict1.items():
print(eachItem)
(0, '关注')
(1, '关注')
(2, '关注')
(3, '关注')
(4, '关注')
>>> #访问字典中的某个元素
>>> print(dict1[3])
关注
>>> #如果试图访问字典中的键的话,一定会报错,但是可以用get()方法
>>> dict1.get(5)
>>> print(dict1.get(5))
None
>>> #当然,我们也可以设置一个具体的值
>>> dict1.get(6,'six')
'six'
>>> #如果那个索引值上有具体的数值,get()设置的值就不会代替原来的值
>>> dict1.get(3,'three')
'关注'
如果想知道一个键是否在字典中,我们可以成员资格操作符:in 和 not in
>>> dict1 = {}
>>> dict1 = dict1.fromkeys(range(5),'number')
>>> dict1
{0: 'number', 1: 'number', 2: 'number', 3: 'number', 4: 'number'}
>>> 1 in dict1
True
>>> 1 not in dict1
False
>>> 5 in dict1
False
>>> 5 not in dict1
True
clear()
清空一个字典
>>> dict1
{0: 'number', 1: 'number', 2: 'number', 3: 'number', 4: 'number'}
>>> dict1.clear()
>>> dict1
{}
如果直接使用变量名赋值为一个空字典的方法来清空字典,这样的做法存在一定的弊端。
>>> a = {"Id":"123"}
>>> a
{'Id': '123'}
>>> b = a
>>> b
{'Id': '123'}
>>> a = {}
>>> a
{}
>>> b
{'Id': '123'}
>>> #a,b指向同一个字典,当给a赋值一个空字典时,原来的字典并没有被真正清空,它还能通过b进行访问,容易造成数据窃取
>>> a = {"Id":"123"}
>>> a
{'Id': '123'}
>>> b = a
>>> b
{'Id': '123'}
>>> a.clear()
>>> a
{}
>>> b
{}
copy()
>>> a = {1:'one',2:'two'}
>>> a
{1: 'one', 2: 'two'}
>>> b = a.copy()
>>> c = a
>>> a
{1: 'one', 2: 'two'}
>>> b
{1: 'one', 2: 'two'}
>>> c
{1: 'one', 2: 'two'}
>>> id(a)
2064835061632
>>> id(b)
2064834555328
>>> id(c)
2064835061632
>>> #a和c的地址一样,而浅拷贝则是对对象一种浅层的拷贝,赋值是对相同数据贴上不同的标签
其他方法
- pop():给定键,弹出对应的值,则对应的值从字典中消失
- popitem():随机弹出字典中的一个值
- setdefault():与get()类似,但是,如果setdefault()在字典中找不到相应的键时,会自动添加
- update([other]):用一个字典或者映射关系去更新另外一个字典
集合
在python中,如果用大括号括起一堆数字但没有体现映射关系,那么就会认为这堆数据是一个集合而不是映射。
N.B.
集合是无序的,也就是不能试图去索引集合中的某一个元素。
创建集合
>>> #1.直接把一堆元素用大括号括起来
>>> set1 = {'Physcis','Chemistry','Boiolgy'}
>>> #2.用set()内置函数
>>> set2 = set(['Physcis','Chemistry','Boiolgy'])
>>> set1 == set2
True
如果要求去除列表[1,2,3,4,5,5,3,1,0]中的重复元素
不用集合版本:
>>> list1 = [1,2,3,4,5,5,3,1,0]
>>> temp = list1[:]
>>> temp
[1, 2, 3, 4, 5, 5, 3, 1, 0]
>>> list1.clear()
>>> list1
[]
>>> for each in temp:
if each not in list1:
list1.append(each)
>>> list1
[1, 2, 3, 4, 5, 0]
集合版本:
>>> list1 = [1,2,3,4,5,5,3,1,0]
>>> list1
[1, 2, 3, 4, 5, 5, 3, 1, 0]
>>> list1 = list(set(list1))
>>> list1
[0, 1, 2, 3, 4, 5]
访问集合
虽然集合中的元素是无序的,无法通过下标进行访问,但是可以通过迭代把集合中的数据一个个读取出来:
>>> set1 = {1,2,3,4,5,4,3,2,1,0}
>>> for each in set1:
print(each, end = ' ')
0 1 2 3 4 5
>>> #当然也可以使用in和not in判断一个元素是否在集合里边
>>> 0 in set1
True
>>> 6 in set1
False
>>> 'xx' in set1
False
>>> #我们也可以使用add()和remove()给集合添加和删除元素
>>> set1
{0, 1, 2, 3, 4, 5}
>>> set1.add(6)
>>> set1
{0, 1, 2, 3, 4, 5, 6}
>>> set1.remove(0)
>>> set1
{1, 2, 3, 4, 5, 6}
不可变集合
frozenset():可以使集合中的数据具有稳定性,不能随意地删除和增加集合中的元素,可以定义出一个不可变集合。
>>> set1 = frozenset({1,2,3,4,5})
>>> set1
frozenset({1, 2, 3, 4, 5})
>>> set1.add(6)
Traceback (most recent call last):
File "<pyshell#2>", line 1, in <module>
set1.add(6)
AttributeError: 'frozenset' object has no attribute 'add'
>>> #因为该集合是不可变集合,所以当试图去增加其中元素时,程序就会报错
文件
文件操作
在Python中,使用open()这个内置函数来打开文件并返回文件对象:
open(file , mode = ‘r’ , buffering = -1 ,encoding = None , errors = None , newline = None , closefd = True , opener = None)
open()这个函数有很多的参数,但作为初学者,只需要关注第一个和第二个参数即可。第一个参数是传入的文件名,如果只有文件名,不带路径的话,那么Python会在当前文件夹中去找到该文件并打开;第二个参数指定文件打开模式
打开模式 | 执行操作 |
---|---|
‘r’ | 以只读方式打开文件(默认) |
‘w’ | 以写入的打开打开文件,会覆盖已存在的文件 |
‘x’ | 如果文件已经存在,使用此模式打开将引发异常 |
‘a’ | 以写入模式打开,如果文件存在,则在末尾追加写入 |
‘b’ | 以二进制模式打开文件 |
‘t’ | 以文本模式打开文件 |
‘+’ | 可读写模式(可添加到其他模式中使用) |
‘U’ | 通用换行符支持 |
使用open()成功打开一个文件之后,他会返回一个文件对象,拿到这个文件对象,我们就可以读取和修改这个文件了
文件对象的方法 | 执行操作 |
---|---|
close() | 关闭文件 |
read(size=-1) | 从文件读取size个字符,当为给size或给定负值的时候,读取剩余的所有字符,然后作为字符串返回 |
readline() | 从文件中读取一整行字符串 |
write(str) | 将字符串str写入文件 |
writelines(seq) | 向文件写入字符串序列seq,seq应该是一个返回字符串的可迭代对象 |
seek(offset,from) | 在文件中移动文件指针,从from(0代表文件的起始位置,1代表当前位置,2代表文件的末尾)偏移offset个字节 |
tell() | 返回当前文件的位置 |
>>> #事先在E盘上创造一个CC.txt的文本文件,内容随意
>>> f = open('E:\\CC.txt')
>>> #open读取完文件之后,我们把它存放在f这个创建文件对象中
>>> f
<_io.TextIOWrapper name='E:\\CC.txt' mode='r' encoding='cp936'>
>>> #操作文件对象
>>> f = open('E:\\CC.txt')
>>> f.read()
'Python\nC++\nJava\nC#'
>>> f.read()
''
>>> #再次读取出了一个新的字符串,说明已经读取到了文件的末尾了
>>>#重新打开文件
>>> f.close()
>>> f = open('E:\\CC.txt')
>>> f.read(2)
'Py'
>>> #读出文件的前两个字符
>>> f.tell()
2
>>> #使用tell()方法得知当前文件书签(指针)的位置,两个英文字符占两个字节
>>> f.close()
>>> f = open('E:\\CC.txt')
>>> f.seek(4,0)
4
>>> #将f文件指针移动到第四个字符
>>> f.readline()
'on\n'
文件的写入
如果需要写入文件,请确保之前的打开模式有’w’或’a’,否则会出错
>>> f = open('E:\\test.txt','w')
>>> #此时在E盘中就会新建一个test.txt文件,为等待写入状态
>>> f.write('我爱Python')
8
>>> #返回的8说明写入了8个字符
>>> f.close()
>>> #写完后关闭,则刚刚写入的内容就会保存到文件中
一个任务
在E盘中有个record2.txt文件:
请按照要求将文件中的数据进行分割并按照以下规则保存起来:
- 将小明的对话单独保存为boy_*.txt文件(去掉”小明:“)。
- 将小红的对话单独保存为girl_*.txt文件(去掉”小红:“)。
- 文中总共有6个文件,分别保存为boy_81~3*.,girl_ * 1~3.txt
def save_file(boy,girl,count):
file_name_boy = 'boy_' + str(count) + '.txt'
file_name_girl = 'girl_' + str(count) + '.txt'
boy_file = open(file_name_boy,'w')
girl_file = open(file_name_girl,'w')
boy_file.writelines(boy)
girl_file.writelines(girl)
boy_file.close()
girl_file.close()
def split_file(file_name):
f = open("E:\\record2.txt")
girl = []
boy = []
count = 1
for each_line in f:
if each_line[:3] != '===':
(role,line_spoken) = each_line.split(':',1)
if role == '小明':
boy.append(line_spoken)
if role == '小红':
girl.append(line_spoken)
else:
save_file(boy,girl,count)
boy = []
girl = []
count += 1
save_file(boy,girl,count)
f.close()
split_file('record2.txt')
文件系统
回顾random模块
>>> import random
>>> random.randint(1,99)
1
>>> random.randint(1,99)
72
>>> random.randint(1,99)
33
>>> random.randint(1,99)
32
模块是一个包含所有你定义的函数和变量的文件,其后缀名是py。模块可以被别的程序引入,以使用该模块的函数等功能。
OS(Operating System)模块
有了OS模块,我们不需要关心什么操作系统下使用什么模块,OS模块会帮你选择正确的模块并调用。
OS模块中关于文件/目录常用的函数使用方法
函 数 名 | 使 用 方 法 |
---|---|
getcwd() | 返回当前工作目录 |
chdir(path) | 改变工作目录 |
listdir(path=’.’) | 列举指定的目录中的文件名(’.‘表示当前目录,’…'表示上一级目录) |
mkdir(path) | 创建单层目录,如该目录已存在抛出异常 |
makedirs(path) | 递归创建多层目录,如该目录已存在抛出异常,注意:'E: \ \ a\ \b’和’E: \ \ b\ \a’并不冲突 |
remove(path) | 删除文件 |
rmdir(path) | 删除单层目录,如该目录非空则抛出异常 |
removedirs(path) | 递归删除目录,从子目录到父目录逐层尝试删除,遇到目录非空则抛出异常 |
rename(old,new) | 将文件old重命名为new |
system(command) | 运行系统的shell命令 |
以下是支持路径操作中常用到的一些定义,支持所有平台
函 数 名 | 使 用 方 法 |
---|---|
os.curdir | 指代当前目录(’.’) |
os.pardir | 指代上一级目录(’.’) |
os.sep | 输出操作系统特定的路径分隔符(Win下为**’ \ \ '**,Linux下为’ / ') |
os.linesep | 当前平台使用的形终止符(Win下为 ’ \ r \ n’,Linux下为’ \ n’) |
os.name | 指代当前使用的操作系统(包括’posix’,‘nt’,‘mac’,‘os2’,‘ce’,‘java’) |
1.getcwd()
还有些情况下需要获得应用程序当前的工作目录(如保存临时文件),那么可以使用getcwd()函数获得:
>>> import os
>>> os.getcwd()
'E:\\Python'
2.chdir(path)
用chdir()函数可以改变当前工作目录,如可以切换到E盘:
>>> os.chdir('D:\\')
>>> os.getcwd()
'D:\\'
3.listdir(path=’.’)
用此函数即可知道当前目录下有哪些文件和子目录。path参数用于指定列举的目录,默认值是’.’,代表当前目录,也可以使用’…'代表上一层目录:
>>> os.listdir()#查找当前的盘的子目录
>>> os.listdir("C:\\")
4.mkdir(path)
mkdir()函数用于创建文件夹,如果该文件夹存在则抛出FileExistsError异常:
>>> import os
>>> os.getcwd()
'E:\\Python'
>>> os.mkdir('E:\\A')
>>> #此时在E盘中创建了一个名为A的文件夹
>>> os.mkdir('E:\\A\\B')
>>> #此时在A中创建了一个B的文件
5.removedirs(path)
删除文件
>>> #事先在B文件中创建了一个test.txt文件
>>> import os
>>> os.remove('E:\\A\\B\\test.txt')
6.rmdir
删除单层目录,如果目录不为空,则会抛出异常
7.removedirs(path)
递归删除多层目录,直到有目录不为空
8.rename(old,new)
将文件old重新命名成new
9.system(command)
运行文件的shell
>>> os.system('calc')
0
>>> #调出电脑自带的计算机
>>> os.system('cmd')
-1073741510
>>> #打开doc命令