本文详细介绍python中的集合,字典,以及异常处理
集合
集合的特点:
- 无序,不能通过index访问
- 不重复,只保留唯一项
numbers = [1, 1, 2, 3, 4]
first = set(numbers)
print(first)
# 去掉1个重复的1后输出 {1, 2, 3, 4}
second = {1, 5}
print(first | second)
# 并集。两个集合的所有合集。{1, 2, 3, 4, 5}
print(first & second)
# 交集。同时存在于两个集合中的。{1}
print(first-second)
# 差集。first有而second没有的。{2, 3, 4}
print(first ^ second)
# 并集减去交集。{2, 3, 4, 5}
second[0]
# 出错了,不能用索引访问,因为集合是无序的
字典
字典非常重要,它指的是键值对。键值对的使用随处可见,比如当下最流行的json,mongodb,redis等等。
键:只能由字符串 或 数值 构成;
值:可以使用任何类型。
# 有两种创建字典的方法
point = {“x”: 1, “y”: 2}
# 创建方法一
point = dict(x=1, y=2)
# 创建方法二
# 这种方法很不错,python各数据结构都有对应的函数可以创建,
# 比如 list(),tuple(),set(),dict()等
point[“x”] = 10
# 设置值
point[“z”] = 20
# 如果键不存在,将创建新的键值对
point[“a”]
# 出错!不存在就读取会出错。需要先检测是否存在
# 有两种方法检测是否存在
if “a” in point:
print(point[“a”])
# 或
print(point.get(“a”, 0))
print(point.get(“a”, None))
# 用get获取,不存在返回0,或返回None等
del point[“x”]
# 删除键值对
for key in point:
print(key)
# 默认遍历的是键
# 可以用拆包方式读取键和值
for key, value in point.items():
print(key, value)
# 或更简单的方法
for key in point:
print(key, point[key])
字典推导
类似列表推导:
将中括号改成大括号,变成set推导;
在set中加入键和冒号则可以变成字典。
values = {x: x*2 for x in range(5)}
print(values)
# 输出 {0: 0, 1: 2, 2: 4, 3: 6, 4: 8}
values = {x*2 for x in range(5)}
print(values)
# 输出 {0, 2, 4, 6, 8}
生成器表达式
列表推导非常好用,但如果生成的数量太多,内存要占用大量数据,影响性能,可以用生成器表达式,避免过多占用内存。
from sys import getsizeof
values = (x*2 for x in range(100000))
# 注意这里是将列表推导的中括号变成了小括号
# 小括号表示生成器表达式,这样不会在内存中生成全部数据
print(“gen:”, getsizeof(values))
# 在我的电脑中输出 gen: 112
# 只有112个数值占用内存
# 同样的,如果我们用常规的中括号
values = [x*2 for x in range(100000)]
print(“List:”, getsizeof(values))
# 在我的电脑中输出是 List: 800984,全部数据都占用了内存
生成器表达式由于事先不知道会有多少项,所以不能使用len函数。
len(values)
# 提示错误!
拆包操作符
一个星号 * :拆分迭代,可拆任何迭代的东西
二个星号 ** : 拆分字典
现代语言或更新版的传统语言一般都加进了拆包功能,如javascript es6版就添加了拆包功能
numbers = [1, 2, 3]
print(numbers)
# 输出[1, 2, 3]
print(*numbers)
# 拆分输出3个数 1 2 3
创建列表时使用拆包
values = list(range(5))
values = [*range(5)]
# 上面两行代码是等同的,一个是常规方法,另一个用了拆包技术
合并列表也非常有用
first = [1, 2]
second = [3]
values = [*first, “a”, *second, *”Hello”]
print(values)
# 输出 [1, 2, ‘a’, 3, ‘H’, ‘e’, ‘l’, ‘l’, ‘o’]
拆包字典,使用双星号 **
first = {“x”: 1}
second = {“x”: 10, “y”: 2}
combined = {**first, **second, “z”: 1}
print(combined)
# 输出 {‘x’: 10, ‘y’: 2, ‘z’: 1}
# 注意有两个键 “x”,以后一个为准
异常
看下基础结构
try:
age = int(input(“Age: “))
except ValueError as ex:
# ex是别名
print(“You didn’t enter a valid age.”)
print(ex)
print(type(ex))
else:
# else也可以省略
print(“No exceptions were thrown.”)
处理不同的异常
try:
age = int(input(“Age: “))
afactor = 10/age
except (ValueError, ZeroDivisionError):
# 捕捉多个异常
print(“You didn’t enter a valid age.”)
else:
print(“No exceptions were thrown.”)
清理
在使用外部资源时,比如打开文件、数据连接、网络连接时,使用后必须关闭掉,如果使用过程发生错误,将不会关闭导致其他程序无法使用,所以需要进行清理。
try:
file=open(“app.py”)
…
except(ValueError,…):
…
else:
…
finally:
file.close()
# finally不管有无异常都将执行,关闭外部资源一般放在这里
with语句
可以不用finally显式地清理或释放外部资源,python的with语句可以做到自动释放。
try:
with open(“app.py”) as file:
# with语句可以自动释放资源,支持with语句的对象都有两个魔术方法:
# __enter__() 和 __exit()__()
# 魔术方法会在讲python类时会详细讲解,现在知道就有双下划线开头的方法就好
print(“File opened.”)
…
except:
…
else:
…
引发异常
有时我们需要主动抛出异常
def calculate_xfactor(age):
if age <= 0:
raise ValueError(“Age cannot be 0 or less.”)
# raise 抛出异常
return 10/age
try:
calculate_xfactor(-1)
except ValueError as error:
print(error)
# 显示我们自定义的提示信息 Age cannot be 0 or less.
抛出异常的成本
抛出异常会增加开销,如果代码中可以不用抛出异常的方法处理,就尽量不抛。我们比较下差别。
from timeit import timeit
code1 = ”’
def calculate_xfactor(age):
if age <= 0:
raise ValueError(“Age cannot be 0 or less.”)
return 10/age
try:
calculate_xfactor(-1)
except ValueError as error:
print(error)
”’
code2 = ”’
def calculate_xfactor(age):
if age <= 0:
return 0
return 10/age
if not calculate_xfactor(-1):
print(“Age cannot be 0 or less.”)
”’
print(timeit(code1, number=10000))
print(timeit(code2, number=10000))
# 分别重复执行code1代码和code2代码 10000次,返回执行时间
# code1代码段就是前面的抛出异常的代码
# code2代码是修改的不抛出异常的解决方法
# 实验结果:code1是0.11秒,code2是0.09,是有些开销差距的。
小结
本文介绍了python中的集合、字典和生成器表达式,以及python的异常处理框架,希望对您有帮助。
下一篇将开始介绍 python类相关知识。