- 数据类型
- 字符串 列表 元组
- 集合 字典 整型 布尔 None 浮点型 字节类型
- 文件操作
- 函数入门
1. 字典类型
定义:字典是一个无序且键不重复且元素只能是键值对的可变容器。
info = {'k1': 111, 'k2':999}
- 键不能重复 重复会被覆盖
- !!!字典的键必须是可哈希的类型 但是值可以随便写!
可哈希的 : int bool str tuple
不可哈希的 : 列表 字典
- !!!怎么测试是否可哈希:
v1 = 123
res = hash(v1)
print(res)
v2 = 'computer'
res = hash(v2)
print(res)
v3 = (11, 22, 33)
res = hash(v3)
print(res)
# 运行结果:
"""
123
8027911955625540668
-5452407625778563439
"""
v1 = [123, 456]
res = hash(v1)
print(res)
- 字典:在Python3.6之前无序,在3.6之后无序。
1.1 定义字典
data = {"k1": 1, 'k2': 2}
info = {
'name': 'computer',
'age': 10,
'status': True,
'hobby': ['sing', 'dance', 'rap', 'basketball']
}
info = {}
存储信息的时候:
data = {
"status":True,
"data": [11, 22, 33]
}
data = {
"status": False,
"data": []
}
1.2 字典独有功能
- 获取值 字典名.get(“键名”, “查不到后返回的值”)
info = {
'name': 'computer',
'age': 10,
'status': True,
'hobby': ['sing', 'dance', 'rap', 'basketball']
}
# 在字典中根据键获取对应的值
v1 = info.get("name")
# 若没有 返回空(None)
v2 = info.get("email")
# 如若找不到,返回指定类型 若能找到 直接返回获取到的值
v3 = get("email", "xxx")
# 案例:使用字典存储用户信息
user_dict = {
"computer": '111',
"science": '222',
"technology": '333'
}
user_name = input("请输入用户名")
user_pwd = input("请输入密码")
# 判断键所对应的值是否存在
db_password = user_dict.get(user)
if db_password is None:
print("用户名不存在")
else:
if db_password == user_pwd:
print('登录成功')
else:
print('登录失败')
- 键 字典名.keys()
info = {
'name': 'computer',
'age': 10,
'status': True,
'hobby': ['sing', 'dance', 'rap', 'basketball']
}
# 获取所有的键
dict_object = info.keys() # 返回值是一个高仿的列表 支持for循环
print(dict_object)
# dict_keys(['name', 'age', 'status', 'hobby'])
for item in info.keys():
print(item)
info = {
'name': 'computer',
'age': 10,
'status': True,
'hobby': ['sing', 'dance', 'rap', 'basketball']
}
v1 = list(info.keys()) # 将这个高仿的列表转换成列表
print(v1)
# ['name', 'age', 'status', 'hobby']
- 获取所有的值 字典名.values()
info = {
'name': 'computer',
'age': 10,
'status': True,
'hobby': ['sing', 'dance', 'rap', 'basketball']
}
v1 = list(info.values()) # 将这个高仿的列表转换成列表
print(v1)
- 获取所有的键、值
info = {
'name': 'computer',
'age': 10,
'status': True,
'hobby': ['sing', 'dance', 'rap', 'basketball']
}
print(info.items()) # 高仿的列表
# dict_items([('name', 'computer'), ('age', 10), ('status', True), ('hobby', ['sing', 'dance', 'rap', 'basketball'])])
for item in info.items():
print(item)
# 牛逼的来啦!!!解包
for key, value in info.items():
print(key, value)
#
列表的解包:
# 列表的解包
v1, v2 = [11, 22]
# 元组的解包
v1, v2 = (11, 22)
1.3 公共功能
- 长度:有多少个键值对 就有多长
info = {
'name': 'computer',
'age': 10,
'status': True,
'hobby': ['sing', 'dance', 'rap', 'basketball']
}
data = len(info)
print(data) # 4
- 索引
info = {
'name': 'computer',
'age': 10,
'status': True,
'hobby': ['sing', 'dance', 'rap', 'basketball']
}
data = info["name"]
print(data) # computer
# 如果写一个不存在的键,那么程序就会报错 和 info.get("xxx")薛薇优点不一样
v2 = info["name"]
- 修改 添加 删除
info = {
'name': 'computer',
'age': 10,
'status': True,
'hobby': ['sing', 'dance', 'rap', 'basketball']
}
# 修改
info["age"] = 100
# 新增
info["email"] = 'xxxxxx@xx.com'
# 删除(若键不存在 那么删除会报错)
del info["age"]
# 判断!!!键!!!是否存在
if 'age' in info:
print('yes')
else:
print('不在')
- for循环
# 循环
for item in info.keys():
print(item)
for item in info.values():
print(item)
for k, v in info.items:
print(key, value)
1.4 练习题
- 对用户输入的数据进行处理,并构成字典:
info = { }
print("请输入信息,输入Q/q终止")
while True:
text = input(">>> ") # computer, 123
if text.upper() == 'Q':
break
else:
string = text.split(",")[0]
number = int(text.split(",")[1])
info[string] = number
- 快递信息分拣 获取所有城市 将城市信息保存到一个字典中 每个地区对应一个列表,对应这个地区的人
addr_list = [
["王*非", "北京市,海淀区","北京市海淀区xxx"],
["李*龙", "上海市,浦东新区","上海市浦东新区xxx"],
["卜*瑜", "北京市,顺义区","当代北辰悦moma"],
["赵*雪", "江苏省,苏州区", "苏州大学"],
""" ['朱*锴', ‘上海市,浦东新区','川沙新镇华川家园33号楼503' ],
['陈*盼','浙江省','杭州市', '闲林街道,西溪华东园,十幢- -单元401。']['司*鹏',‘河南省,鹤壁市’, '淇滨大道310号鹤壁京立医院' ],
['聂*睿', ‘河北省,石家庄市',,中山路勒泰中心写字楼b座11层'],['张*', 辽宁省,本溪市', ,明兴丽城九号楼四单元' ],
['冉*晗', '河北省,石家庄市',,体育南大街385号'],
['高*杰', '北京市,朝阳区','广渠路42号院3号楼,408'],
['李*国', '安徽省,合肥市', ,新站区淮合花园'],
['常*源', '江苏省,南京市',‘白下路242号,南京市红十字医院,放射科' ],['张*玉','河北省,沧州市’,'新居然家居广场'],
['王*川','上海市,奉贤区','南桥镇贝港七区' ],
['冀*庆','河北省,保定市',‘河北大学坤兴园生活区'],
['胡+晨',‘浙江省,宁波市',‘浙江省宁波市江东区中山首府A座2004室'],['尹*婷' '湖北省,武汉市',‘武汉大学信息学部'],
['李*东','辽宁省,大连市’,'大关- -街3号3-3-1'],
[ '张*',天津市,河西区','隆昌路94号(天津科技馆) '],
[ '刘+', ,湖北省,黄冈市', '城关镇']
"""
]
info = {}
for item in addr_list:
name = item[0]
city = item[1].split(",")[0]
if city not in info:
info[city] = []
info[city].append(name)
else:
info[city].append(name)
print(info)
# {'北京市': ['王*非', '卜*瑜'], '上海市': ['李*龙'], '江苏省': ['赵*雪']}
1.5 字典的扩展-嵌套
- 容器:元组 列表 字典(键必须是可哈希的-字符串 整型 元组 布尔)
1.6字典的扩展-为什么键必须是可哈希的——从底层看
由于底层存储原理,导致根据键获取值的速度特别快。
v1 = [11, 22, 33, 44, 55, 66]
info = {...}
info["name"]
info.get("name")
if "xx" in info:
pass
v1 = [11, 22, 33, 44, 55, 66]
if 44 in v1:
pass
目前不可哈希的只有:列表和字典
小结
- 字符串
- 独有 大小写 去除空白(左右两边) 分割 替换 拼接(join) 字符填充 是否是数字
- 公共 长度 索引 切片 for循环 in是否包含
- 列表
- 独有 追加 插入 删除(值) 删除(索引) 清空 排序
- 公共 长度 索引(读 删 改) 切片(读 删 改) for循环 in是否包含
- 元组
- 无独有功能
- 公共功能 长度 索引 切片 for循环 in是否包含
- 字典
- 独有 get keys values items
- 公共 len 索引键(读 删 改 添加) for循环 in是否包含
info = {
"k1": 123,
"k2": 456
}
2. 集合
集合是一个无序 可变 元素必须可哈希 且元素不重复的容器。
2.1定义
v1 = {11, 22, 33, 44, 55}
- 无序 无法索引 切片
- 可变
v1 = {11, 22, 33, 44, 55}
v1.add(66)
print(v1)
# {11, 22, 33, 44, 55, 66}
- 元素不重复
- 元素必须是可哈希的
# 不可哈希:list dict set
# 其他的可哈希
- 什么时候用集合?
- 只有不希望重复的数据集合的时候
- 通过网络爬虫技术从网上爬图片,维护一个集合,维护所有已经下载过的地址
- 注意事项:定义空值:
# define None list
v1 = []
v2 = list()
# define None tuple
v3 = ()
v4 = tuple()
# define None dict
v5 = {}
v6 = dict()
# define None set
v7 = set()
2.2 独有功能
- 添加元素 add()
v1 = {11, 22}
v1.add(33)
v1 = set()
v1.add(111)
v1.add(222)
- 删除元素 discard() 如果不存咋,不会报错 与列表的remove不同
v1 = {11, 22}
v1.discard(11)
- 交集 intersection() — 生成一个不同于任意两个集合的新集合
v1 = {11, 22, 33, 44}
v2 = {11, 22, 55, 66}
# 方式1
v3 = v1.intersection(v2)
print(v3) # {11, 22}
# 方式2
v4 = v1 & v2
print(v4)
- 并集
v1 = {11, 22, 33, 44}
v2 = {11, 22, 55, 66}
# 方式1
v3 = v1.union(v2)
print(v3) # {11, 22}
# 方式2
v4 = v1 | v2
print(v4)
- 差集
v1 = {11, 22, 33, 44}
v2 = {11, 22, 55, 66}
# v1里面有 v2里面没有
s1 = v1.difference(v2) # v1中有但v2中没有的值
s2 = v1 - v2
print(s1)
print(s2)
2.3 公共功能
- 长度
v1 = {11, 22, 33, 44}
data = len(v1)
print(data) # 4
- for循环
v1 = {11, 22, 33, 44}
for item in v1:
print(item)
- in是否包含(效率高 速度快 => 字典查询键的速度一样)
v1 = {11, 22, 33, 44}
if 11 in v1:
pass
else:
pass
2.4 存储
3. 容器之间的转换
- list
v1 = [11, 22, 33, 44]
- tuple
v2 = (11, 22, 33, 44)
- set
v3 = {11, 22, 33, 44}
- 三者之间可以相互转换,转换的原则:想转换谁,就把谁的英文名字包裹一下。
v1 = [11, 22, 33, 44]
res = tuple(v1)
print(res) # (11, 22, 33, 44)
- 当元组或者列表转换成集合时,会自动去重。
4. None类型
None表示空值。
# v1设置为空
v1 = None
v2 = None
v3 = None
# 再从内存创建一个字符串 让v1指向字符串
v1 = "computer"
# v2设置为空字符串
v4 = ""
v5 = ""
v4 = "computer"
以上这两者的区别是:初始化的时候,尽量使用None初始化,这样会节省内存。在效果上没区别
5. 布尔类型
真假 True/False
其他的很多类型的值会转换为布尔值,有真有假
- 转换后为False:
0 -> False
"" -> False
[] -> False
() -> False
set() -> False
{} -> False
None -> False
- 其他的转换为布尔后,都为False
- 如果将布尔值放在条件或者循环语句后面:
if True:
pass
while True:
pass
if 1 > 2:
pass
# 内部会自动转换为布尔值 True/False
if "computer":
pass
while 2:
pass
6. 浮点型(float)
浮点型就是我们常说的小数。
v1 = 3.24
v2 = 9.8
由于在计算机底层对浮点型数据的存储原理,有时候浮点型获取的值会不太精确。——这与语言无关,每种语言都有这个问题。
v1 = 0.1
v2 = 0.2
print(v1 + v2)
v1 = 0.3
v2 = 0.2
print(v1 + v2)
- 如果要做特别精确的计算的时候,使用Python的decimal模块。
import decimal
v1 = decimal.Decimal("0.1")
v2 = decimal.Decimal("0.2")
print(v1 + v2)
7. 字节类型 bytes
name = "计算机" # str字符串,底层是unicode编码
data = name.encode("utf-8") # bytes字节,底层是UTF-8编码
print(data) # b'\xe8\xae\xa1\xe7\xae\x97\xe6\x9c\xba'
name = "计算机" # str字符串,底层是unicode编码
data = name.encode("gbk") # bytes字节,底层是gbk编码
print(data) # b'\xbc\xc6\xcb\xe3\xbb\xfa'
如果以后获得了一个字节,字节.decode转换为字符串.
name = "计算机" # str字符串,底层是unicode编码
data = name.encode("gbk") # bytes字节,底层是gbk编码
old = data.decode("utf-8")
print(data) # 计算机
8. 文件操作
普通的文本文件。
三个基本步骤
# 打开
# 操作
# 关闭文件
- 写文件
# 打开文件
# - "unicome.txt" 文件路径
# - mode="wb" 以写文件的模式打开
file_object = open("unicome.txt", mode="wb") # wb模式 如果文件不存在则会创建文件 如果存在则默认将文件内容清空
# 写内容
name = "计算机" # unicode
file_object.write(name.encode("utf-8"))
file_object.write(name.encode("utf-8"))
# 关闭文件
file_object.close()
练习题:注册用户,每次注册一个用户,写入一行
# user = input('username')
# pwd = input("password")
with open("unicome.txt", mode="wb") as file_object:
while True:
user = input("username")
pwd = input("password")
if user.upper() == "Q":
break
file_object.write((user + " " + pwd + "\n").encode("utf-8"))
with open("unicome.txt", mode="wb") as file_object: # 以写字节模式添加
while True:
user = input("username")
if user.upper() == "Q":
break
pwd = input("password")
line = "{} {}\n".format(user, pwd)
# 写到内存中的缓冲区 还没有写到硬盘 关闭后才会写到硬盘
file_object.write(line.encode("utf-8"))
file_object.flush() # 强制将内存中的数据写入到硬盘
- 追加
with open("unicome.txt", mode="ab") as file_object: # 在文件尾部进行追加 如果不存在那么会创建文件
# 永远写到文件的尾部
while True:
user = input("username")
if user.upper() == "Q":
break
pwd = input("password")
line = "{} {}\n".format(user, pwd)
# 写到内存中的缓冲区 还没有写到硬盘 关闭后才会写到硬盘
file_object.write(line.encode("utf-8"))
file_object.flush() # 强制将内存中的数据写入到硬盘
- 读
file_object = open("unicome.txt", mode="rb")
data = file_object.read() # 读取文件所有内容
print(data)
# b'\xe5\x8d\x9c\xe4\xbc\x9f\xe4\xbb\x95 123\ngood 123456\n123 123456\n'
data_string = data.decode("utf-8")
print(data_string)
row_list = data_string.split("\n")
# ['computer 123', 'good 123456', '123 123456', '']
row_list = data_string.strip().split("\n")
# ['computer 123', 'good 123456', '123 123456']
file_object.close()
如果有100G的文件,那么用上述的模式去读,你8G内存的电脑可以读取100G的文件吗?根本不可能!!!所以在读取大文件的时候,需要一行一行去读。
# 这种方式无法判断文件在哪结束
file_object = open("unicome.txt", mode="rb")
line1 = file_object.readline()
print(line1)
line2 = file_object.readline()
print(line2)
file_object.close()
# 或者你可以使用这种方式读取
for line in file_object:
line_string = line.decode("utf-8").strip() # .strip()去除每一行的换行
print(line_string)
练习题:将文件中的某一块数据读取出来。比如获取企业数据
# 文件内容如下:
SZ300019,硅宝科技,9.50,+0.53,+5.91%,-6.13%,423.46万,3943.10万,1.55%,24.58,1.65%,31.40亿
SZ002756,永兴材料,16.18,+0.90,+5.89%,-7.34%,247.83万,3910.01万,1.34%,18.38,2.98%,58.21亿
SZ002498,汉缆股份,6.11,+0.34,+5.89%,+102.99%,2.01亿,12.04亿,6.05%,43.98,0.62%,202.93亿
SZ002980,华盛昌,62.41,+3.46,+5.87%,+319.14%,969.65万,5.99亿,29.09%,51.97,-,83.21亿
SZ002371,北方华创,176.88,+9.80,+5.87%,+101.00%,1006.35万,17.45亿,2.20%,276.58,0.04%,875.76亿
SZ300139,晓程科技,8.71,+8.48,+5.83%,+0.23%,4423.87万,3.82亿,20.11%,亏损,0.00%,23.84亿
SZ000636,风华高科,24.51,+1.33,+5.74%,+64.61%,5605.61万,13.61亿,6.26%,71,71,8.00%,219.42亿
SZ000564,供销大集,4.06,+日.22,+5.73%,+69.87%,2.98亿,11.89亿,14.86%,亏损,8.08%,244.52亿
SZ002612,朗姿股份,7.84,+0.42,+5.66%,-19.34%,548.71万,4191.22万,2.31%,1224.17,4.23%,34.69亿
SH600176,中国巨石,9.39,+0.50,+5.62%,-13.85%,3256.19万,3.02亿,0.93%,16.97,2.14%,328.87亿
SH603313,梦百合,24.10,+1.28,+5.61%,+14.16%,356.10万,8446.14万,1.05%,21.72,0.00%,82.23亿
SZ300279,和晶科技,5.49,+8.29,+5.58%,-8.50%,2328.20万,1.31亿,5.33%,亏损,0.00%,24.65亿
# 注意,后面有一些空行
list_ = []
with open("demo.txt", "rb") as fp:
for line in fp:
new_line = line.decode("utf-8").strip()
if new_line != "":
data = new_line.split(",")[1]
list_.append(data)
print(list_)
# ['硅宝科技', '永兴材料', '汉缆股份', '华盛昌', '北方华创', '晓程科技', '风华高科', '供销大集', '朗姿股份', '中国巨石', '梦百合', '和晶科技']
练习题:用户注册和用户登录的功能
- 注册:输入用户名和密码
- 登录:和文件中进行比对,看是否对得上
with上下文:
# 编写文件的时候,可能会关闭文件,这样会导致一些问题,一定要关闭文件——with上下文管理
with open("文件名", "打开模式") as file_object:
# 这里面进行文件操作,只要在缩进里面,文件夹就会一直打开
# 离开缩进时自动关闭文件
文件打开模式
rb 读
wb 写
ab 追加
- wb 写
with open("file_path", mode="wb") as fp:
fp.write("写一些东西".encode("utf-8")) # 手动压缩
- w 写
with open("file_path", mode="w", encoding="utf-8") as fp:
fp.write("写一些东西") # 此时不用再手动编码压缩,内部自动encode压缩
- ab 追加
with open("file_path", mode="ab") as fp:
fp.write("写一些东西".encode("utf-8")) # 手动压缩
- a 追加
with open("file_path", mode="a", encoding="utf-8") as fp:
fp.write("写一些东西")
- rb 读
with open("file_path", mode="rb") as fp:
data = fp.read() # 读取到的文件都是内部原始被压缩的之后的utf-8编码的效果
data.decode("utf-8")
- r 读
with open("file_path", mode="r", encoding="utf-8") as fp:
data = fp.read()