Python3.7学习笔记14-数据的存储 。之前我们学习了python3的六大数据类型的定义及使用。本节我们来深入学习下数据的存储原理并且分析下常用数据类型的性能

一、列表的存储

  • 列表是动态的,它需要存储指针来指向对应的元素(对于int类型的元素,占用8字节)。 列表是可变的,所以需要额外存储已经分配大长度大小8字节。这样才可以实时追踪列表空间的使用情况,当空间不足的时,及时分配额外空间。
l = []
print(l.__sizeof__())  # 空列表的存储空间为40字节

l.append(1)
l.__sizeof__()  # 72  加入了元素1之后,列表为其分配了可以存储4个元素的空间(72 - 40) / 8 = 4

l.append(2)
l.__sizeof__()  # 72  由于之前分配了空间,所以加入元素2,列表空间不变

l.append(3)
l.__sizeof__()  # 72  同上

l.append(4)
print(l.__sizeof__())  # 72  同上

l.append(5)
print(l.__sizeof__())  # 104  加入元素5之后,列表的空间不足,所以又额外分配了可以存储4个元素的空间

m = [1, 2, 3, 4, 5, 6, 7, 8, 9]
l = l + m
print(l.__sizeof__())  # 拼接了一个新列表。此时共有元素14个。占用内存=40+14*8=152。该列表分配的内存已经使用完毕。

l.append(1)
print(l.__sizeof__())  # 列表新增一个元素。此时列表分配内存216。还有56字节即8个数字的剩余空间。


打印结果:

40
72
104
152
216

 

二、元组的存储

  • 元组是静态变量。所以对它来说。存储空间就是固定的
x = ()
print(x.__sizeof__()) # 占用空间24 因为不需要额外存储长度和指针共16字节

y = (1,2,3)
a = [1,2,3]

print(y.__sizeof__(),a.__sizeof__()) #存储同样的元素。元组比列表要少存储16字节

打印结果:

24
48 64

 

三、列表和元组性能比较

列表和元组初始化同样的元素时间如下

MacBook-Pro:~ zhonglinglong$ python3 -m timeit 'a=(1,2,3,4,5)'

20000000 loops, best of 5: 15 nsec per loop

MacBook-Pro:~ zhonglinglong$ python3 -m timeit 'a=[1,2,3,4,5]'

5000000 loops, best of 5: 70.2 nsec per loop

通过元组和列表存储的比较。我们可以得出一些结论。

  • 元组比列表轻量级一些,性能要优于列表。(数据越大差距越明显) 而且python有缓存机制。对于静态变量比如元组。如果占用的内存不大,在它不使用的时候,会缓存下来。当下次创建静态变量的时候。 就不会开辟新的内存。而是分配之前缓存过的空间。这样能大大加快程序的运行速度。
  • 对比初始化相同的元素的列表和元组,我们会发现列表需要的时间是元祖大概5倍。(数据越大5倍的时间就会放大了)

列表和元组的使用场景 数据和数量不变。比如前端有个选择省份的。这种数据是不会变化的。我们可以返回元组类型的数据。 数据和数量都变的。我们选择用列表返回。原因是因为我们可以在一个列表上进行操作。但是元组的话要新建一个变量。重新分配内存。

 

四、字典

字典的存储数据原理和列表差不多。都是先分配内存空间。然后随着字典项的增加。会增加字典的内存。

我们主要来看看。字典和列表在查找方面性能比较。

我们来看下面的例子。有这样的场景。电商后台产品。对应有产品ID,产品名称,产品价格。分别用列表和字典存储。然后去查询。可以看到。当使用列表存储数据。需要遍历去查找。而且每一次查询都的从开始遍历。当数据量非常大的时候。这个性能是非常差的。当使用字典存储数据。只需要查找key是否存在字典里面。存在即取出。(字典是进行过性能高度优化的数据结构。它内部原理是一张哈希表。有兴趣的可以深入去了解)。

id_price = [
    (1, 180),
    (2, 90),
    (3, 100),
    (4, 50)
]


def find(product_id):
    for id, perce in id_price:
        if id == product_id:
            return perce
    return None


bzf = True
while bzf:
    product_id = input('请输入产品id:')
    for id, perce in id_price:
        if str(id) == product_id:
            print('产品价格:' + str(perce))
            bzf = False
            break
    if bzf:
        print('产品不存在!请重新输入')


id_price_ = {
    1: 180,
    2: 90,
    3: 100,
    4: 50
}

bzf_ = True
while bzf_:
    product_id = input('请输入产品id:')

    if int(product_id) in id_price_:
        print('产品价格:' + str(id_price_[int(product_id)]))
        bzf_ = False
        break
        
    else:
        print('产品不存在!请重新输入')

五、集合

集合和字典也是一致的。其内部结构也是一张哈希表。只是少了key value

集合和字典一样通常使用的场景是。对元素的高效查找 去重。