Python中最常见的两种数据结构:列表(list)和元组(tuple),它们都是可以存放任意数据类型的有序集合。

ls = [1, 2, 'hello', 'world'] # 列表中同时含有 int 和 string 类型的元素

tup = ('jason', 22) # 元组中同时含有 int 和 string 类型的元素

list与tuple的区别:

一、列表是动态的,长度大小不固定,可以随意的增、删、改元素;元组是静态的,长度大小固定,不可随意增、删、改元素。

ls = ['1', '2', '3', '4']
ls.append('5')
ls[2] = '6'
print ls
['1', '2', '6', '4', '5']
tp = ('1', '2', '3', '4')
tp[2] = 6
报错:
TypeError: 'tuple' object does not support item assignment

要想改变元组,只能重新开辟一块内存,创建新的元组。原来的元组还是没有改变

new_tuple = tp + ('5',)
print tp, new_tuple

('1', '2', '3', '4')   ('1', '2', '3', '4', '5')

二、存储方式的差异

tup = (3, 2, 3, 7)
ls = [3, 2, 3, 7]
print tup.__sizeof__(), ls.__sizeof__()
56 72

可以看出,对列表和元组,我们放置了相同的元素,但是元组的存储空间,却比列表要少 16 字节。

原因:由于列表是动态的,所以它需要存储指针,来指向对应的元素(上述例子中,对于 int 型,8 字节)。另外,由于列表可变,所以需要额外存储已经分配的长度大小(8 字 节),这样才可以实时追踪列表空间的使用情况,当空间不足时,及时分配额外空间。

l = []
print l.__sizeof__()
40 //  空列表的存储空间为 40 字节
l.append(1)
print l.__sizeof__()
72 //  加入了元素 1 之后,列表为其分配了可以存储 4 个元素的空间 (72 - 40)/8 = 4
l.append(2)
l.append(3)
l.append(4)
print l.__sizeof__()
72 // 同上
l.append(5)
print l.__sizeof__()
104 //  加入元素 5 之后,列表的空间不足,所以又额外分配了可以存储 4 个元素的空间

所以,。我们可以看到,为了减小每次增加 / 删减 操作时空间分配的开销,Python 每次分配空间时都会额外多分配一些,这样的机制 (over-allocating)保证了其操作的高效性:增加 / 删除的时间复杂度均为 O(1)。但是对于元组,情况就不同了。元组长度大小固定,元素不可变,所以存储空间固定。

从列表和元组的存储方式上,我们可以学习到,元组要比列表更加轻量级一些, 所以总体上来说,元组的性能速度要略优于列表。

list和tuple常用的函数:

相互转换:

 

list((1, 2, 3))
[1, 2, 3]
tuple([1, 2, 3])
(1, 2, 3)

 

常用的内置函数:

ls = ['6', '7', '8', '9', '8', '5', '3']
print ls.count('8')
2
print ls.index('5')
5

ls.reverse()
print ls
['3', '5', '8', '9', '8', '7', '6']
ls.sort()
print ls
['3', '5', '6', '7', '8', '8', '9']
print reversed(ls)
<listreverseiterator object at 0x101f00f50>
print list(reversed(ls))
['6', '7', '8', '9', '8', '5', '3']



tup = (3, 2, 3, 7, 8, 1)
print tup.count(3)
2
print tup.index(8)
4
print reversed(tup)
<reversed object at 0x109680f50>
print tuple(reversed(tup))
(1, 8, 7, 3, 2, 3)
print list(reversed(tup))
[1, 8, 7, 3, 2, 3]
print sorted(tup)
[1, 2, 3, 3, 7, 8]

count(item) 表示统计列表 / 元组中 item 出现的次数。

index(item) 表示返回列表 / 元组中 item 第一次出现的索引。

list.reverse() 和 list.sort() 分别表示原地倒转列表和排序(注意,元组没有内置的这两个 函数)。

reversed() 表示对列表 / 元组进行倒转,但是会返回一个倒转后对象,再通过list或tuple来转换。

 

sorted()sorted() 表示对列表 / 元组进行排序,但是会返回一个排好序的新的列表。

 

总结:

列表是动态的,长度可变,可以随意的增加、删减或改变元素。列表的存储空间略大于元 组,性能略逊于元组。

元组是静态的,长度大小固定,不可以对元素进行增加、删减或者改变操作。元组相对于 列表更加轻量级,性能稍优