本篇文章為大家帶來了關於python的相關知識,其中主要介紹了列表和元組的相關問題,可以使用靈活的列表(list)和元組( tuple),來進行資料儲存,下面我們先簡單了解下列表和元組的基本使用,希望對大家有幫助。
推薦學習:python學習教程
在我們實際開發中,經常需要將一群組資料儲存起來,以便使用。如果學習了其他的語言可能知道數組(Array)這個資料結構,它就可以將多個資料進行存儲,存取資料可以透過數組下標的方式,的進行取得。如果你是python開發者,那麼可以使用更靈活的清單(list)和元組(tuple),來進行資料儲存。下面我們先簡單了解下列表和元組的基本使用。
清單是動態的,長度可以改變,可以隨意增加,修改或刪除元素。
a = list() b = [] # 可以通过range快速创建list c = list(range(1,6)) print("a:", a) print("b:", b) print("c:", c) # a: [] # b: [] # c: [1, 2, 3, 4, 5]
append:在清單的最後新增一個元素
>>l = [] >>l.append("python") >>l ['python']
extend:使用可迭代物件中的所有元素來擴展列表
>>l = ["python"] >>t = ["java"] >>l.extend(t) >>l ['python', 'java']
insert:在給定的位置插入一個元素。第一個參數是要插入的元素的索引,所以list_name.insert(0, x)
插入清單頭部
>>l = ["python", "java"] >>l.insert(1,"go") >>l ['python', 'go', 'java']
#remove(x):從清單中刪除值為x的第一項。如果沒有需要刪除的值,那就拋出異常
>>l = ["python", "java"] >>l.remove("java") >>l ['python'] >>l.remove("test") Traceback (most recent call last): File "<input>", line 1, in <module> ValueError: list.remove(x): x not in list
pop: 刪除清單中給定位置的元素並傳回它。如果沒有給定位置,pop()
將會刪除並傳回清單中的最後一個元素
>>l = ["python", "java", "go"] >>l.pop() 'go' >>l ['python', 'java'] >>l.pop(1) 'java' >>l.pop(1) Traceback (most recent call last): File "<input>", line 1, in <module> IndexError: pop index out of range
del: Python 中的關鍵字,專門用來執行刪除操作,它不僅可以刪除整個列表,也可以刪除列表中的某些元素
>>l = ["python", "java", "go", "js"] >>del l[0:1] >>l ['java', 'go', 'js'] >>del l[0] >>l ['go', 'js']
clear(): 移除列表中的所有元素。等價於del a[:]
>>l = ["python", "java", "go", "js"] >>l.clear() >>l []
ps: 這裡注意和del 的區別,clear是清空, del list_name 是刪除,記憶體也釋放
>>l = ["python", "go", "java"] >>l[0] = "PYTHON" >>l ['PYTHON', 'go', 'java']
>>l = ["python", "go", "java"] >>l[0:2] = "PYTHON", "GO" >>l ['PYTHON', 'GO', 'java'] >>l[0:2] = ["python", "go"] >>l ['python', 'go', 'java']
>>l ['python', 'go', 'java'] >>l.index("python") 0 >>l.index("python1") Traceback (most recent call last): File "<input>", line 1, in <module> ValueError: 'python1' is not in list
>>l ['python', 'go', 'java'] >>l.count("PYTHON") 0 >>l.count("python") 1
>>l ['go', 'java', 'python'] >>l.sort(reverse=True) >>l ['python', 'java', 'go'] >>l.sort() >>l ['go', 'java', 'python']
>>l = [1,2,3,4,5] >>l.reverse() >>l [5, 4, 3, 2, 1]
a[:]
>>l [5, 4, 3, 2, 1] >>a = l.copy() >>a [5, 4, 3, 2, 1]
append() 。若要從堆疊頂端取出一個元素,使用
pop() ,不用指定索引。
stack = [] stack.append(1) stack.append(2) stack.append(3) stack.append(4) stack.pop() # 4 stack.pop() # 3 stack.pop() # 2 stack.pop() # 1 # 注意捕捉错误
from collections import deque queue = deque(["python", "go", "java"]) queue.append("python") queue.append("go") print(queue) queue.popleft() queue.popleft() print(queue)
deque(['python', 'go', 'java', 'python', 'go']) deque(['java', 'python', 'go'])
a = [x ** 2 for x in range(10)] b = [(x, y) for x in [1, 2, 3] for y in [3, 1, 4] if x != y] # 嵌套列表推导式 matrix = [ [1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], ] c = [[row[i] for row in matrix] for i in range(4)] print("a:", a) print("b:", b) print("c:", c)
a: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] b: [(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)] c: [[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
a = 1, 2, 3 print("a", a) b = (1, 2, 3) print("b", b) # 将字符串转换成元组 tup1 = tuple("hello") print("将字符串转换成元组", tup1) # 将列表转换成元组 list1 = ['Python', 'Java', 'C++', 'JavaScript'] tup2 = tuple(list1) print("将列表转换成元组", tup2) # 将字典转换成元组 dict1 = {'a': 100, 'b': 42, 'c': 9} tup3 = tuple(dict1) print("将字典转换成元组", tup3) # 将区间转换成元组 range1 = range(1, 6) tup4 = tuple(range1) print("将区间转换成元组", tup4)
a (1, 2, 3) b (1, 2, 3) 将字符串转换成元组 ('h', 'e', 'l', 'l', 'o') 将列表转换成元组 ('Python', 'Java', 'C++', 'JavaScript') 将字典转换成元组 ('a', 'b', 'c') 将区间转换成元组 (1, 2, 3, 4, 5)
a = (1, 2, 3, 4, 5) # 通过下标 print(a[0]) # 通过切片:a[start : end : step] print(a[0:4:2])
1 (1, 3)
a = (1, 2, 3, 4, 5) del a
l = (1,2,3,4) id(l) # 4497372488 l = l + (5,6) id(l) # 4494985832
l = [1,2,3,4] id(l) # 4499169160 l = l + [5,6] id(l) # 4495787016
list_t = [] print("列表初始化时候大小:", list_t.__sizeof__()) tuple_t = () print("元组初始化时候大小:", tuple_t.__sizeof__())
列表初始化时候大小: 40 元组初始化时候大小: 24
看到结果有没有发现列表比元组大18字节,那么问题来了:这18字节是怎么来的?这是由于列表是动态的,它需要存储指针来指向对应的元素(占用 8 个字节)。另外,由于列表中元素可变,所以需要额外存储已经分配的长度大小(占用 8 个字节),这样才能实时追踪列表空间的使用情况。但是对于元组,情况就不同了,元组长度大小固定,且存储元素不可变,所以存储空间也是固定的。
tuple_t = (1, 2) print("元组hash值:", hash(tuple_t)) list_t = [1, 2] print("列表hash值:", hash(list_t))
执行结果
Traceback (most recent call last): File "/Users/linjian/MonitorCenter/MonitorCenter/apps/t6.py", line 4, in <module> print("列表hash值:", hash(list_t)) TypeError: unhashable type: 'list' 元组hash值: 3713081631934410656
从上面的结果可以发现元组是可以被hash,但列表却是不可以。如果基础扎实的应该会反应过来,python中hash需要满足是不可变类型的数据结构(字符串str、元组tuple、对象集objects)
# 初始化一个相同元素的列表和元组使用情况 (djangoDemo) MonitorCenter % python -m timeit 'x=(1,2,3,4,5,6)' 100000000 loops, best of 3: 0.0103 usec per loop (djangoDemo) MonitorCenter % python -m timeit 'x=[1,2,3,4,5,6]' 10000000 loops, best of 3: 0.0514 usec per loop # 元组和列表索引操作对比 (djangoDemo) MonitorCenter % python -m timeit 'x=(1,2,3,4,5,6)' 'y=x[3]' 10000000 loops, best of 3: 0.0267 usec per loop (djangoDemo) MonitorCenter % python -m timeit 'x=(1,2,3,4,5,6)' 'y=x[3]' 10000000 loops, best of 3: 0.0265 usec per loop
上面的运行结果显示: 元组初始化远快于列表 ,大概有五倍的差距,但是索引操作的时候速度没有多大差距
截止目前为止,我们可以简单总结列表和元组的区别有如下:
再说使用场景前先讲一下,在python后台,对静态数据做一些资源缓存,通常因为垃圾回收机制的存在,一些变量不使用,python就会回收他们所占的内存,但是对于一些静态变量(比如说元组),当他们占用不大时候(长度1~20的元组),python会暂时缓存这部分内存,这样下次就可以不再向操作系统发出请求,分配内存资源,而是直接使用用缓存中之前的内存空间,这样大大加快了程序的运行速度。所以一般有时候数据量不大,我经常使用元组替代列表。到目前为止我们可以简单的总结出场景可以如下所示:
(djangoDemo) MonitorCenter % python -m timeit 'x=list()' 10000000 loops, best of 3: 0.087 usec per loop (djangoDemo) MonitorCenter % python -m timeit 'x=[]' 100000000 loops, best of 3: 0.0177 usec per loop
通过上面的测试可以知道是[]快。list()函数调用,python中函数调用会创建stack并且会进行参数检查,[]是一个内置C函数,可以直接调用,因此效率更高。
(djangoDemo) MonitorCenter % python -m timeit 'x = [1,2,3]' 'x*=3' 10000000 loops, best of 3: 0.0903 usec per loop (djangoDemo) MonitorCenter % python -m timeit 'x = [1,2,3]' 'x = x * 3' 10000000 loops, best of 3: 0.104 usec per loop
从结果可以看出是*效率会低点。*= 中会预分配,不足的时候扩容,但是* 会按照每次的量进行分配大小
list_1 = [1, 2, 3, 4] list_2 = [1, 2, 3, 4] list_3 = [1, 2, 3, 4] list_4 = [1, 2, 3, 4] for idx, item in enumerate(list_1): del item for idx, item in enumerate(list_2): list_2.remove(item) for idx, item in enumerate(list_3[:]): list_3.remove(item) for idx, item in enumerate(list_4): list_4.pop(idx) print("list_1", list_1) print("list_2", list_2) print("list_3", list_3) print("list_4", list_4)
结果
list_1 [1, 2, 3, 4] list_2 [2, 4] list_3 [] list_4 [2, 4]
list_2为什么输出是[2,4]? 因为在第一次删除后,list_2变成了 [2,3,4], 然后在删除轮循到到第二个数据也就是3(大部分都以为是2,但是2从原来的下表2变为1),可以参看下面的
give next element: 0 0 ---> 1 1 2 2 3 3 4 give next element: 1 0 2 1 ---> 3 2 4 give next element: 2 0 2 1 4
list_3 为什么是[], 还记得之前我们说copy时候,copy等于[:](浅拷贝),所以轮询的和删除的不是同一内存的数据。
list_4可以结合list_2思考,因为第一次删除,第二次删除是下标2,但是数据变了,下标2的数据不是原来的2,而是3
推荐学习:python教程
以上是python列表和元組詳解(實例詳解)的詳細內容。更多資訊請關注PHP中文網其他相關文章!