Lecture 6 - CS50’s Introduction to Programming with Python (harvard.edu)
Notes
list文件类型
- 每行一个元素
open
# name = input("What's your name? ")
# file = open("names.txt", "w")
# file.write(name)
# file.close()
name = input("What's your name? ")
file = open("names.txt", "a")
file.write(f"{name}\n")
file.close()
注意:
- 打开文件:
file = open("names.txt", "w")
的"w"
每次都是重写整个文件;file = open("names.txt", "a")
的"a"
是append,在文件后面继续追加 - 写入文件:
file.write(f"{name}\n")
,记得换行 - 关闭文件:
file.close()
with
with open("names.txt", "a") as file:
file.write(f"{name}\n")
注意:
with
可以自动关掉文件,不用额外close- 记得换行
read
with open("names.txt", "r") as file:
lines = file.readlines()
for line in lines:
print("hello,", line.rstrip())
注意:
.rstrip()
可以去除额外的换行file.readlines()
能按行读取文件内容- 读文件也需要打开和关闭文件
将文件读取为list
names = []
with open("names.txt") as file:
for line in file:
names.append(line.rstrip())
for name in sorted(names):
print(f"hello, {name}")
注意:
- list增加是
append()
,list排序是sorted
- 读取文件为list
dic文件类型
- 每行多个元素
读csv
students.csv
Hermoine,Gryffindor
Harry,Gryffindor
Ron,Gryffindor
Draco,Slytherin
students.py(list)
students = []
with open("students.csv") as file:
for line in file:
name, house = line.rstrip().split(",")
students.append(f"{name} is in {house}")
for student in sorted(students):
print(student)
students.py(dic)
students = []
with open("students.csv") as file:
for line in file:
name, house = line.rstrip().split(",")
student = {"name": name, "house": house}
students.append(student)
for student in students:
print(f"{student['name']} is in {student['house']}")
注意:
name, house = line.rstrip().split(",")
student = {"name": name, "house": house}
dic 排序
students = []
with open("students.csv") as file:
for line in file:
name, house = line.rstrip().split(",")
students.append({"name": name, "house": house})
for student in sorted(students, key=lambda student: student["name"]):
print(f"{student['name']} is in {student['house']}")
注意:
lambda
函数:key=lambda student: student["name"]
即对于一个匿名函数,给定一个学生(对象),获取其name元素并返回为key(键)
csv库
引入csv库,可以更加方便的处理csv
import csv
students = []
with open("students.csv") as file:
reader = csv.DictReader(file)
for row in reader:
students.append({"name": row["name"], "home": row["home"]})
for student in sorted(students, key=lambda student: student["name"]):
print(f"{student['name']} is in {student['home']}")
注意:
- csv库读取:
csv.DictReader(file)
读取有表头的csv(就直接知道每一列是什么意思了),csv.reader(file)
读取没有表头的csv #csv库 - csv读取结果是行(row)
写csv
import csv
name = input("What's your name? ")
home = input("Where's your home? ")
with open("students.csv", "a") as file:
writer = csv.DictWriter(file, fieldnames=["name", "home"])
writer.writerow({"name": name, "home": home})
PIL库
import sys
from PIL import Image
images = []
for arg in sys.argv[1:]:
image = Image.open(arg)
images.append(image)
images[0].save(
"costumes.gif", save_all=True, append_images=[images[1]], duration=200, loop=0
)
pip install Pillow
python costumes.py costume1.gif costume2.gif
作业
lines
import sys
# 获取list长度
def getlen(my_list):
total=len(my_list)
for line in my_list:
# 判断是不是注释或者空行
if line.strip().startswith("#") or line.lstrip()=="":
total-=1
return total
# testlen=["1","2,3,4","","# nihao","222"]
# print(getlen(testlen))
inputlist=[]
try:
if len(sys.argv)>2:
raise ValueError
elif len(sys.argv)==1:
raise TypeError
elif sys.argv[1].endswith(".py") ==0:
raise NameError
with open(sys.argv[1]) as file:
for line in file:
inputlist.append(line.rstrip())
print(getlen(inputlist))
except ValueError:
sys.exit("Too many command-line arguments")
except TypeError:
sys.exit("Too few command-line arguments")
except FileNotFoundError:
sys.exit("File does not exist")
except NameError:
sys.exit("Not a Python file")
难点:
- 封装了一个判断list长度的函数 #判断list长度
- 判断空格:
line.lstrip()==""
lstrip() - 判断注释:
line.strip().startswith("#")
- 判断空格:
- 不同异常退出提示不同
pizza
import sys
import csv
from tabulate import tabulate
menu=[]
try:
if len(sys.argv)>2:
raise ValueError
elif len(sys.argv)==1:
raise TypeError
elif sys.argv[1].endswith(".csv") ==0:
raise NameError
with open(sys.argv[1]) as file:
reader = csv.DictReader(file,fieldnames=["pizza1","Small","Large"])
for row in reader:
menu.append({"pizza": row["pizza1"], "Small": row["Small"],"Large":row["Large"]})
print(tabulate(menu,headers="firstrow",tablefmt="grid"))
# 注意区别:headers="firstrow",那么表头就是csv里的第一行
# headers="keys",表头是键名("pizza","small","large")
except ValueError:
sys.exit("Too many command-line arguments")
except TypeError:
sys.exit("Too few command-line arguments")
except FileNotFoundError:
sys.exit("File does not exist")
except NameError:
sys.exit("Not a csv file")
难点:
- 导入有表头的csv
reader = csv.DictReader(file,fieldnames=["pizza1","Small","Large"])
fieldnames相当于给表头起别名
- 用tabulate来输出美化后的表格
- 注意区别:
headers="firstrow"
,那么表头就是csv里的第一行 headers="keys"
,表头是键名("pizza","small","large"
)
- 注意区别:
scourgify
# 把一个2列的表拆分为3列的表
import sys
import csv
hp=[]
try:
if len(sys.argv)>3:
sys.exit("Too many command-line arguments")
elif len(sys.argv)<3:
sys.exit("Too few command-line arguments")
elif sys.argv[1].endswith(".csv") ==0 or sys.argv[2].endswith(".csv") ==0:
sys.exit("Not a csv file")
# 读文件,将文件放入hp字典中
with open(sys.argv[1]) as file:
reader = csv.DictReader(file)
for row in reader:
last,first=row["name"].strip().split(", ")
hp.append({"first": first, "last":last,"house": row["house"]})
# 写文件,把hp文件写入另一csv
with open(sys.argv[2],"w",newline="") as file:
writer = csv.DictWriter(file, fieldnames=["first","last","house"])
writer.writeheader()
for row in hp:
writer.writerow({"first":row["first"],"last":row["last"],"house":row["house"]})
except FileNotFoundError:
sys.exit("File does not exist")
难点:
- 其实可以读写在一起(或者嵌套打开),不必分开,因为之后也没有其他地方要用到读的文件,所以没必要用字典hp[]来中转:
with open(sys.argv[1]) as input, open(sys.argv[2], "w", newline="") as output:
reader = csv.DictReader(input)
writer = csv.DictWriter(output, fieldnames=["first", "last", "house"])
writer.writeheader()
for row in reader:
last_name, first_name = row["name"].strip().split(", ")
writer.writerow(
{"first": first_name, "last": last_name, "house": row["house"]}
)
- 将字典按行写入csv中:
with open(sys.argv[2],"w",newline="") as f:
,记得"w"
授予写入权限,newline=""
可以正常解析换行符,否则会多空行writer.writerow({"first":row["first"],"last":row["last"],"house":row["house"]})
涉及到嵌套字典怎么取用元素- 有表头的csv要先
writer=csv.DictWriter()
,再writer.writeheader()
,再逐行写入
shirt
import os.path
import sys
from PIL import Image,ImageOps
images = []
try:
if len(sys.argv)>3:
sys.exit("Too many command-line arguments")
elif len(sys.argv)<3:
sys.exit("Too few command-line arguments")
for im in sys.argv[1:]:
if im.endswith(".jpg") ==0 and im.endswith(".png") ==0 and im.endswith(".jpeg") ==0:
sys.exit("Invalid input")
# 判断后缀名是否一样
if os.path.splitext(sys.argv[1])[1] != os.path.splitext(sys.argv[2])[1]:
sys.exit("Input and output have different extensions")
shirt=Image.open("shirt.png")
im= Image.open(sys.argv[1])
# 将before.jpg缩减成shirt的大小
im = ImageOps.fit(im, shirt.size)
# 把shirt粘贴在before.jpg上,im.paste(shirt, mask=shirt)?神奇的用法,可以去掉shirt以外的东西
im.paste(shirt, shirt)
im.save(sys.argv[2])
except FileNotFoundError:
sys.exit("File does not exist")
难点:
- 判断后缀名是否一致:
splitext()
函数- 导入库:
os.path
- 取后面部分
- 导入库:
- 图片粘贴:
- 导入图片相关函数:
from PIL import Image,ImageOps
paste()
:把shirt粘贴在before.jpg上,im.paste(shirt, mask=shirt)?神奇的用法,可以去掉shirt以外的东西
- 导入图片相关函数: