Lesson 16
Introduction
不是所有的数据都能以pile的形式存储,一般情况下,把数据存储成序列更有用。Python提供了几种处理序列的方式,list就是其中一个常见方法,但是tuple是一种更小更快存储方法。那么,list和tuple有那些不同呢?开始做实验吧。
Difference between List and Tuple
第一个小不同,list用方括号定义,而tuple用圆括号定义。
# List example
prime_numbers = [2,3,5,7,11,13,17]
# Tuple example
perfect_squares = (1,4,9,16,25,36) # first difference: [],()
# Display length
print("# Primes = ", len(prime_numbers))
print("# Squares = ", len(perfect_squares))
# Primes = 7
# Squares = 6
我们现在试着打印了list和tuple的序列长度,暂时是没有区别的。下面把元素都打印出来试试。
# Iterate over both sequences
for p in prime_numbers:
print("Prime: ", p)
for n in perfect_squares:
print("Squares: ", n)
Prime: 2
Prime: 3
Prime: 5
Prime: 7
Prime: 11
Prime: 13
Prime: 17
Squares: 1
Squares: 4
Squares: 9
Squares: 16
Squares: 25
Squares: 36
到目前为止,还是看不出来有什么不同。那么我们试着把适用于两个数据结构的内建方法打印出来看看。
print("List methods")
print(dir(prime_numbers))
print(80*"_")
print("Tuple methods")
print(dir(perfect_squares))
List methods
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
________________________________________________________________________________
Tuple methods
['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'count', 'index']
可以发现,List有’append’, ‘clear’, ‘copy’, ‘count’, ‘extend’, ‘index’, ‘insert’, ‘pop’, ‘remove’, ‘reverse’, ‘sort’这些方法,而Tuple只有’count’, ‘index’。这也就意味着List比Tuple要占用更多的存储空间。
# utilize sys.getsizeof to get the memery
import sys
list_eg = [1,2,3,'a','b','c',True,3.1415]
tuple_eg = (1,2,3,'a','b','c',True,3.1415)
print("list size = ", sys.getsizeof(list_eg))
print("tuple_size = ", sys.getsizeof(tuple_eg))
list size = 128
tuple_size = 112
终于可以看到他们之间的区别了,这一点在数据量很大的时候就显而易见了,Tuple更适合规模大且只需要简单操作存储的数据。
当然,从内建函数中也可以得到,List可以增删改,但是Tuple是不能变的,也可以称之为immutable。Python对牺牲了Tuple的功能,赋予它更快的速度。
# utilize timeit to test the speed
import timeit
list_test = timeit.timeit(stmt="[1,2,3,4,5]",
number=1000000)
tuple_test = timeit.timeit(stmt="(1,2,3,4,5)",
number=1000000)
print("List time : ", list_test)
print("Tuple time :", tuple_test)
List time : 0.12573448600005577
Tuple time : 0.02030748099991797
从这个小实验中可以得到,Tuple在速度方面的优势还是很明显的。
Experiment on Tuple
empty_tuple = ()
test1 = ("a")
test2 = ("a", "b")
test3 = ("a", "b", "c")
print(empty_tuple)
print(test1)
print(test2)
print(test3)
()
a
('a', 'b')
('a', 'b', 'c')
为什么test1打印出来是字符串?而不是和其他一样的tuple格式呢?
print(type(test1))
print(type(test2))
<class 'str'>
<class 'tuple'>
果然是字符串,原因在于当只有一个元素时,需要以逗号结尾。
test1 = ("a",)
print(test1)
('a',)
Alternative Construction of Tuple
# another way
test1 = 1,
test2 = 1,2
test3 = 1,2,3
print(test1)
print(test2)
print(test3)
print(type(test1))
print(type(test2))
print(type(test3))
(1,)
(1, 2)
(1, 2, 3)
<class 'tuple'>
<class 'tuple'>
<class 'tuple'>
Tuple Assignment
# (age, country, know_python)
survey = (23, "China", True)
age = survey[0]
country = survey[1]
know_python = survey[2]
print("Age = ",age)
print("Country = ",country)
print("Know Python? ", know_python)
Age = 23
Country = China
Know Python? True
用List同样的方式提取tuple中的元素是有效的,但是tuple提供了更高效的方法。
survey2 = (24, "America", True)
age, country, know_python = survey2
print("Age = ",age)
print("Country = ",country)
print("Know Python? ", know_python)
Age = 24
Country = America
Know Python? True
同时也要注意一个错误,这种方式去提取tuple中的元素,一定要一一对应,举个例子:
x,y,z = (1,2)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-16-6f419fd02ba5> in <module>()
----> 1 x,y,z = (1,2)
ValueError: not enough values to unpack (expected 3, got 2)
a,b,c = (1,2,3,4)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-17-2e0282f2aef3> in <module>()
----> 1 a,b,c = (1,2,3,4)
ValueError: too many values to unpack (expected 3)
Conclusion
以上就是Tuple的内容,与List相比,构建速度很快。需要注意的是如果只有一个元素,要记得以逗号结尾。在用tuple特有的方式提取元素是,注意一一对应,不能多也不能少。总的来说,Tuple是有它的优势的,考虑代码的质量是需要考虑考虑它与List谁更适合自己的子模块。
Youtube source:
https://www.youtube.com/watch?v=bY6m6_IIN94&list=PLi01XoE8jYohWFPpC17Z-wWhPOSuh8Er-