Python数据结构——list
list 列表
什么是list
列表是Python中特有的一種線(xiàn)性數(shù)據(jù)結(jié)構(gòu),列表是可變的,有序的,我們可以用選擇操作符來(lái)改變?nèi)我馕恢玫闹?#xff0c;和數(shù)組不同的是,列表可以同時(shí)保存不同類(lèi)型的元素(異構(gòu))。
在CPython中,list是一個(gè)存儲(chǔ)指針的長(zhǎng)度可變的數(shù)組(用C++的話(huà)來(lái)說(shuō)是一個(gè)動(dòng)態(tài)數(shù)組)。也就是說(shuō)列表中的每個(gè)元素存儲(chǔ)的并不是對(duì)象本身,而是一個(gè)指向?qū)ο蟮囊谩?/p>
list有哪些功能
list的創(chuàng)建
我們可以直接使用選擇操作符來(lái)創(chuàng)建列表,也可以使用list()來(lái)創(chuàng)建
stuff = list() stuff = []list的方法
索引
因?yàn)榱斜淼谋举|(zhì)依然是一個(gè)數(shù)組,所以也支持?jǐn)?shù)組的索引操作
時(shí)間復(fù)雜度:
下表索引:O(1)O(1)O(1)
切片索引:O(k)O(k)O(k)
增加元素
append()
append(x)操作可以再列表的末尾添加一個(gè)元素
時(shí)間復(fù)雜度:
和數(shù)組一樣,時(shí)間復(fù)雜度為O(1)O(1)O(1)
insert()
insert(i, x)可以用來(lái)在索引i處添加元素x
時(shí)間復(fù)雜度:
要想在索引i插入某個(gè)元素,我們必須先將索引i及之后的元素向后移動(dòng)一位,然后再給索引i賦值
因此插入元素時(shí)需要的后移操作的次數(shù)和列表內(nèi)元素的個(gè)數(shù)有關(guān),所以時(shí)間復(fù)雜度為O(n)O(n)O(n)
extend()
extend(iterable)操作將一個(gè)可迭代對(duì)象的每一個(gè)元素添加到列表末尾
lis = [1, 2, 3, 'a', 4] lis.extend("hello") print(lis) >>> [1, 2, 3, 'a', 4, 'h', 'e', 'l', 'l', 'o']時(shí)間復(fù)雜度:
操作過(guò)程為先遍歷讀取可迭代對(duì)象的每個(gè)元素,然后添加到列表末尾,時(shí)間復(fù)雜度為O(k)O(k)O(k)
刪除元素
pop()
pop(i=-1)用來(lái)移除列表中的某個(gè)元素并返回,可以傳入索引值,默認(rèn)為-1。也就是說(shuō)pop()默認(rèn)移除最后一位元素。
這里我們可以看到,當(dāng)我們使用pop()時(shí),盡管索引為4的元素仍然指向4,但是我們的列表長(zhǎng)度已經(jīng)縮短了。有興趣的可以參考Python的列表實(shí)現(xiàn),以及resize()的用法
時(shí)間復(fù)雜度:
如果只是移除最后一位元素,那么時(shí)間復(fù)雜度為O(1)O(1)O(1)
如果移除的是列表中的元素,那么還需要進(jìn)行數(shù)據(jù)前移,前移的次數(shù)也和列表大小有關(guān),因此時(shí)間復(fù)雜度為O(n)O(n)O(n)
remove()
remove(x)操作可以移除x元素在數(shù)組中的第一個(gè)匹配項(xiàng)
當(dāng)我們r(jià)emove(5)時(shí),會(huì)從列表中刪除對(duì)元素5的引用。
時(shí)間復(fù)雜度:
remove(x)操作可以視為先查找再移除最后數(shù)據(jù)前移,而查找和數(shù)據(jù)前移都和數(shù)組的大小有關(guān),所以時(shí)間復(fù)雜度為O(n)O(n)O(n)。但實(shí)際使用上,remove()的操作效率較低,因?yàn)橥瑫r(shí)執(zhí)行了查找和數(shù)據(jù)前移操作。
del
del操作可以根據(jù)索引值刪除列表中的元素,也可以切片刪除或直接刪除整個(gè)列表
lis = [1,2,3,4,5] del lis[0] >>> [2, 3, 4, 5]del lis[0:2] >>> [4, 5]del lis[:] >>> []同時(shí),del操作也可以用來(lái)刪除變量,要注意的是del刪除的是引用而不是對(duì)象本身。關(guān)于del語(yǔ)句的詳細(xì)用法以后再細(xì)說(shuō)。可閱讀
時(shí)間復(fù)雜度:
因?yàn)閐el也需要先查找并再刪除后前移元素,所以時(shí)間復(fù)雜度以也是O(n)O(n)O(n)
clear()
clear()操作等價(jià)于del list[:],直接刪除列表全部元素
時(shí)間復(fù)雜度:
根據(jù)直覺(jué),我認(rèn)為clear()操作的時(shí)間復(fù)雜度為O(n)O(n)O(n),因?yàn)槲覀冃枰粩嗟匮h(huán)來(lái)刪除所有的元素。但是在這篇文檔中提到clear()的時(shí)間復(fù)雜度為O(1)O(1)O(1)。
后來(lái)在這里找到了解釋。clear()操作的時(shí)間復(fù)雜度取決于我們的Python解釋器。對(duì)于CPthyon來(lái)說(shuō),時(shí)間復(fù)雜度確實(shí)是O(n)O(n)O(n),因?yàn)閘ist需要去主動(dòng)刪除每一個(gè)引用以避免內(nèi)存泄漏。但是對(duì)于其他的解釋器(PyPy)來(lái)說(shuō),有可能實(shí)現(xiàn)O(1)O(1)O(1)。
import timefor size in 10000, 100000, 1000000, 10000000:lis = [0] * sizestart = time.time()lis.clear()end = time.time()print(f'{size:<10} : {end - start}')>>> 10000 : 2.47955322265625e-05 100000 : 0.0002560615539550781 1000000 : 0.00399017333984375 10000000 : 0.03731894493103027可以看到,對(duì)于CPython來(lái)說(shuō),時(shí)間確實(shí)是呈線(xiàn)性增長(zhǎng)的。
修改元素
list的元素修改直接通過(guò)索引完成
時(shí)間復(fù)雜度:
如果是下標(biāo)索引,時(shí)間復(fù)雜度為O(1)O(1)O(1)
如果是切片索引,時(shí)間復(fù)雜度為O(k)O(k)O(k),可看成下標(biāo)索引重復(fù)kkk次
查找元素
index()
index(x, start, end)操作可以返回元素x第一次出現(xiàn)的索引值,如果沒(méi)找到會(huì)出現(xiàn)ValueError異常
時(shí)間復(fù)雜度:
為了查找特定元素,我們需要遍歷列表,所以時(shí)間復(fù)雜度為O(n)O(n)O(n)
count()
count(x)操作可返回元素x在列表中出現(xiàn)的次數(shù)
時(shí)間復(fù)雜度:
同樣的,需要遍歷整個(gè)列表才能得到結(jié)果,所以時(shí)間復(fù)雜度為O(n)O(n)O(n)
總結(jié)
其實(shí)Python中的list和C++中的vector很類(lèi)似,如果想看底層實(shí)現(xiàn),可以去看看cpython解釋器的具體實(shí)現(xiàn)。
| [i] | O(1)O(1)O(1) | |
| [i1, i2] | O(k)O(k)O(k) | |
| append(x) | O(1)O(1)O(1) | |
| insert(i, x) | O(n)O(n)O(n) | |
| extend(iterable) | O(k)O(k)O(k) | |
| pop() | O(1)O(1)O(1) | |
| pop(i) | O(n)O(n)O(n) | |
| remove(x) | O(n)O(n)O(n) | |
| del | O(n)O(n)O(n) | |
| clear() | O(n)O(n)O(n) | 取決于解釋器 |
| index(x) | O(n)O(n)O(n) | |
| count(x) | O(n)O(n)O(n) |
其他常用方法
Split()函數(shù)
split() 函數(shù)可以將字符串按照規(guī)律分割為小片段(也被稱(chēng)為字),然后存儲(chǔ)在一個(gè)列表中,例如:
>>> string = "hello world" >>> words = string.split() >>> print(words) ['hello', 'world']我們還可以指定分隔符(默認(rèn)為空格),例如:
>>> string = "Hello_world_what_a_good_day" >>> words = string.split() >>> print(words) ['Hello_world_what_a_good_day']>>> words = string.split("_") >>> print(words) ['Hello', 'world', 'what', 'a', 'good', 'day']list的優(yōu)點(diǎn)和缺點(diǎn)
優(yōu)點(diǎn):
缺點(diǎn):
list的特性
待補(bǔ)充…
相關(guān)章節(jié)
Python數(shù)據(jù)結(jié)構(gòu)——array
Python數(shù)據(jù)結(jié)構(gòu)——list
Python數(shù)據(jù)結(jié)構(gòu)——tuple
總結(jié)
以上是生活随笔為你收集整理的Python数据结构——list的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Python数据结构——array
- 下一篇: Python数据结构——tuple