环境
- windows 10 64位
- python 3.8
获取对象的大小
使用 sys.getsizeof
可以检查 Python
对象的内存使用情况。让我们试试这个
In [1]: import sys
...:
...: mylist = range(0, 10000)
...: print(sys.getsizeof(mylist))
48
In [2]:
喂,等等,为什么10000个元素的列表居然只占了48个字节?
这是因为 range
方法返回一个仅仅表现的像列表的对象。这个范围,是一个生成器对象,它比使用实际的数字列表要高效得多。如果需要,它会生成一个新数字,而不是实际存储所有数字。
下面我们通过使用列表推导创建来自同一范围的数字列表,看看它的大小
In [3]: import sys
...:
...: myreallist = [x for x in range(0, 10000)]
...: print(sys.getsizeof(myreallist))
87616
In [4]:
果然,这个列表占用空间就大了很多。需要注意的一点是,sys.getsizeof
仅适用于内置数据类型,对于自定义数据类型,就只能借助于其它的分析工具,这里推荐一个工具包,Pympler
,它提供了一个名为 asizeof()
的方法,更多信息,请阅读 Pympler
官方文档,地址 https://pympler.readthedocs.io/en/latest/
用元组而不是列表
元组和列表都是 Python
内置的序列数据类型。它们有很多的共同点
- 可以在一个变量中保存多个值
- 是有序的
- 使用索引访问元素
不过,它们还是有区别的:
- 元组是不可变的,一旦定义了就不能改变
- 元组使用括号() 而不是方括号[]
- 因为元组是不可变的,所以它是可散列的,可以作为字典中的键值
- 元组可以有任意长度
如果不需要修改列表,请考虑使用元组。这里有几个好处
- 创建速度更快
- 可以防止意外操作,因为无法修改。这在处理并发时尤其有用,比如线程或进程同时访问同一个列表
- 需要更少的内存
关于内存使用,我们看个例子
In [1]: import sys
In [2]: l = [1, 2, 3]
In [3]: t = (1, 2, 3)
In [4]: sys.getsizeof(l)
Out[4]: 80
In [5]: sys.getsizeof(t)
Out[5]: 64
In [6]:
内联if/else
可以在语句中内联( inline
) if.. else
结构来获得简洁但仍然非常易读的代码
In [6]: def get_status(error):
...: return 'OK' if not error else 'We have a problem'
...:
In [7]: get_status(error=True)
Out[7]: 'We have a problem'
In [8]: get_status(error=False)
Out[8]: 'OK'
In [9]:
else语句与循环
在 Python
循环语句是可以加一个 else
语句,它的基本语法是
for
循环
for x in <some iterable>:
...
else:
....
对应到 while
循环,是这样的
while <some condition>:
...
else:
...
除非循环碰到 break
语句,否则默认情况下会执行 else
的部分,这种写法对于从其它传统编程语言过来的童鞋,可能会有点不太适应。
通常你会在循环中做一些事情,直到满足某个条件。如果满足该条件,则设置某种标志,例如 found = True
,并中断循环,然后在接下来的代码中,需要检查标志是否已设置( if found...
)。使用 else
语句,可以让你的代码更加精简。
字典合并
从 Python
3.5开始,合并字典变得比以前更容易了,而从3.9开始,就更简单了
dict1 = { 'a': 1, 'b': 2 }
dict2 = { 'b': 3, 'c': 4 }
merged = { **dict1, **dict2 }
print (merged)
# {'a': 1, 'b': 3, 'c': 4}
# Python >= 3.9 only
merged = dict1 | dict2
print (merged)
# {'a': 1, 'b': 3, 'c': 4}
如果有重叠的键,第一个字典中的键值将被覆盖