@python学习记录
编码
计算机只能识别01,不同位数的01产生不同组合,这种组合作为计算机识别不同状态的基础。ASCII编码就是规定了英文字母(区分大小写)以及常用字符用哪些位数的二进制来表示,7个比特位就足够完成编码。欧洲某些语言有只有英文字母还不够,例如注音符,此时拓展到8个比特位的01来编码。对于中文而言用了16个比特位来表示部分常用汉字。
国际通用编码:Unicode。
我的理解是为了解决编码解码时有些语言用不到那么多的比特位就可以完成转码所以出了UTF-8编码,这是一种可变字节的编码,会根据识别情况变化,具体过程不清楚,查了一下也挺复杂的。
encode/decode
'想编码的内容'.encode('使用的编码表')
'想解码的内容'.decode('使用的编码表')
print(b'\xe6\x88\x91\xe7\x88\xb1\xe4\xbd\xa0'
.decode('utf-8'))
文件读写
#打开文件,我使用的是绝对路径,a表示追加写入,r表示只读,w表示覆盖写入,编码方式:encoding,一般常用utf-8编码表
file=open(r'C:\Users\lenvov\Desktop\name.txt', 'a', encoding='utf-8')
file.write('难念的经')#追加写入,不会清除已有内容
file.close()#关闭文件
#读文件
file=open(r'C:\Users\lenvov\Desktop\name.txt', 'r', encoding='utf-8')
filecontent=file.read()
print(filecontent)
file.close()
需要注意的是绝对路径是与当前文件无关,代码文件和处理文件在不在一起无所谓,而相对路径需要代码文件和处理文件在同一个文件夹里。Windows系统下python里绝对路径表示有一下两种
r'C:\Users\lenvov\Desktop\name.txt' #路径前加小写字母r
'C:\\Users\\lenvov\\Desktop\\name.txt'#使用\\表示\,区分转义字符\n,\b等情况
content=filename.readlines()#按行读取
for i in content:
data=i.split()#字符串切分,.join()表示字符串连接
sum=0
for score in data[1:]: #遍历每一行的分数
sum=sum+float(score) #每一行加和
results=data[0]+str(sum)#将每一行0位的姓名和加和结果连接
print(result)
练习15.2 图片复制
自己写的
file=open('photo1.png','rb')#rb为二进制可读,open函数的读写追加方式不同,后续需要总结
pic=file.read()#读取图片
file1 = open('photo2.png','wb')#以只写的方式打开photo2,凡是涉及'w'的打开方式,没有找到便会自动创建路径文件
file1.write(pic)#将pic写入新创建的photo2文件,至此完成同一目录下的图片复制和重命名。
#刚接触,思维上有个冲击是重新创建文件路径和名字这里
老师给的
with open('photo2.png','rb') as file: # 以“rb”模式打开图片
data = file.read()
with open('photo3.png','wb') as newfile: # 以“wb”模式写入
newfile.write(data)
数据转移中变化
对txt文件中的数据进行加和,按名字对应存在新文件中
范例:
file1 = open('scores.txt','r',encoding='utf-8')
file_lines = file1.readlines()
file1.close()
final_scores = []
for i in file_lines:
data =i.split()#split函数用于分割字符串,若字符串间有空格split()默认按照空格进行分割,当字符串之间没有空格有也没有其他字符会自动识别为一串字符。此外有特殊字符的可以按照特殊字符分割。
sum = 0 # 先把总成绩设为0
for score in data[1:]: # 遍历列表中第1个数据和之后的数据
sum = sum + int(score) # 然后依次加起来,但分数是字符串,所以要转换
result = data[0]+str(sum)+'\n' # 结果就是学生姓名和总分
print(result)
final_scores.append(result)
print(final_scores)
sum1 = open('winner.txt','w',encoding='utf-8') #创建新的路径文件名
sum1.writelines(final_scores)#按行写入
sum1.close()
练习15.3
将上面得到的winner文件中按照总分由高到低重新排列,放到新文档中
一开始受到前面范例代码的影响,只想着用split去分割姓名和总分,但一直报错:超出索范围,打印winner文件后发现此时的姓名和总分之间没有空格或其他特殊字符使用split只会得到一串名字和总分的字符串,不能进行处理。
自己写的
import re
#引入正则表达式模块,这个模块主要处理字符串,感觉功能很强大
file1 = open('winner.txt', 'r', encoding='utf-8')
file_lines = file1.readlines() # 按行读取
file1.close()
def find_name(strings): #定义函数,作用:只留下字符串中的中文字符
pattern = re.compile(r'[^\u4e00-\u9fa5]')#找字符串中的非中文
name = re.sub(pattern, '', strings)#将非中文部分替换为[]
return name #返回剩下的中文字符
dict_final = {}
list_name = []
scores = []
for i in file_lines:
score = re.sub('\D', '', i)#将非数字部分替换为[]
name = find_name(i)
dict_final[score] = name#将score作为keys,name作为值存到字典里,一开始是score作为值name作为键,但是不知道为什么定义的get_key函数总是返回空值,没找到原因,所以还是改了这里。
scores.append(score)
final = sorted(dict_final.keys(), reverse=True)#降序排列
print(dict_final)
print(final)
# def get_key(dict, value):
# return [k for k, v in dict.items() if v == value]
for i in final:
score_rank = dict_final[i] + i + '\n' #这里都是字符不需要转格式
list_name.append(score_rank)
print(list_name)
with open('winner_new.txt','w',encoding='utf-8') as newfile:
newfile.writelines(list_name)
newfile.close() #存到新文件中
范例:
# 下面注释掉的代码,皆为检验代码(验证每一步的思路和代码是否达到目标,可解除注释后运行)。
file1 = open('winner.txt','r',encoding='utf-8')
file_lines = file1.readlines()
file1.close()
dict_scores = {}
list_scores = []
final_scores = []
# print(file_lines)
# print(len('\n'))
# 打印结果为:['罗恩102\n', '哈利383\n', '赫敏570\n', '马尔福275\n']
# 经过测试,发现'\n'的长度是1。所以,名字是“第0位-倒数第5位”,分数是“倒数第4位-倒数第二位”。
# 再根据“左取右不取”,可知:name-[:-4],score-[-4:-1]
for i in file_lines: # i是字符串。
print(i)
name = i[:-4] # 取出名字(注:字符串和列表一样,是通过偏移量来获取内部数据。)#这里分数都是三位数(-4到-2),因此名字应该是-4以前的,不包括-4位
score = int(i[-4:-1]) # 取出成绩,当分数位数不同时,此种方法不可用
print(name)
print(score)
dict_scores[score] = name # 将名字和成绩对应存为字典的键值对(注意:这里的成绩是键)
list_scores.append(score)
# print(list_scores)
list_scores.sort(reverse=True) # reverse,逆行,所以这时列表降序排列,分数从高到低。
print(list_scores)
for i in list_scores:
result = dict_scores[i] + str(i) + '\n'
# print(result)
final_scores.append(result)
print(final_scores) # 最终结果
winner_new = open('winner_new.txt','w',encoding='utf-8')
winner_new.writelines(final_scores)
winner_new.close()
练习15.4:古诗默写
自己写的
with open ('poem2.txt','r') as file:
lines = file.readlines()
print(lines)
with open ('poem2.txt','w') as file1:
for linep in lines:
if linep in ['一弦一柱思华年。\n','此情可待成追忆,\n']:
file1.write('__________.\n')
else:
file1.write(linep)
反思:对字典的操作不熟悉,不熟悉的函数使用应先查更详细的用法,以免出一些难以理解的错误
出现 ValueError i/o operation on closed file可能是file.close()的位置不对,也可能是with语句下的代码块没有放在with block里面,还可能是指定某个编码规则输出后影响后续的输出。