深入剖析Python的列表和元組
1. 定義
列表
和元組
,都是一個可以放置任意數(shù)據(jù)類型的有序集合。
在大多數(shù)編程語言中,集合內(nèi)元素的數(shù)據(jù)類型必須保持一致,但在 Python 的列表與元組中,沒有這個約束。
示例
列表 List = [‘Tom’, 22, 33, ‘tony’]
元組 Tuple = (‘China’, 10)
如上列表與元組的示例,列表與元組集合內(nèi)同時存放了 int 類型和 string 類型的元素
2. 區(qū)別
列表是動態(tài)的,長度大小不固定,可以隨意地新增、刪除、修改集合內(nèi)元素
input:
test_list = ['Tom', 22, 33, 'tony'] test_tuple = ('jack', 10) # test_list新增元素 test_list.append('100') test_list.append('200') print(test_list) # test_list修改元素 test_list[0] = 'xiaomin' print(test_list) # test_list刪除元素 test_list.pop() print(test_list)
output:
['Tom', 22, 33, 'tony', '100', '200']
['xiaomin', 22, 33, 'tony', '100', '200']
['xiaomin', 22, 33, 'tony', '100']
從輸入,輸出可以證明列表支持集合內(nèi)元素的新增、刪除、修改
元組是靜態(tài)的,長度大小固定,不可以新增、刪除、修改集合內(nèi)元素
input:
test_tuple = ('jack', 10) # test_tuple修改元素 test_tuple[0] = 'xiaomin' print(test_tuple)
output:
Traceback (most recent call last):
File "test001.py", line 5, in <module>
test_tuple[0] = 'xiaomin'
TypeError: 'tuple' object does not support item assignment
從輸入,輸出可以證明元組不支持集合內(nèi)元素的修改
,新增和刪除也不支持,大家可以自己動手實(shí)驗(yàn)下。
這也證明了Python中元組是靜態(tài)不可變的。
如果就想在原有元組集合中添加元素,有沒有辦法可以實(shí)現(xiàn)呢?
答案:“有的”,見如下示例
input:
test_tuple = ('jack', 10) new_test_tuple = test_tuple + (20, 'xiaomin') print(new_test_tuple)
output:
('jack', 10, 20, 'xiaomin')
雖然能實(shí)現(xiàn)想要的效果,但并不是真正意義上的原元組集合基礎(chǔ)上元素的添加,而是創(chuàng)建了一個新的元組 new_test_tuple 來實(shí)現(xiàn)。
3. 索引
Python 中的列表和元組都支持正負(fù)數(shù)索引,正常索引區(qū)間,非正常索引區(qū)間取值。驗(yàn)證如下:
input:
test_list = [100, 200, 300, 400, 500] # 列表支持區(qū)間索引取值: 取索引下標(biāo)為1至倒數(shù)第2個元素之間的所有元素,規(guī)則:左閉右開 print(test_list[1:-1]) # 列表支持單個正數(shù)索引取值: 取正數(shù)第2個元素 print(test_list[2]) # 列表支持單個負(fù)數(shù)索引取值: 取倒數(shù)第2個元素 print(test_list[-2]) # 列表支持非區(qū)間索引取值: 從倒數(shù)第2個元素一直往前取所有 print(test_list[:-1]) print("*" * 20) test_tuple = ('jack', 10, 20, 'tom') # 元組支持區(qū)間索引取值: 取索引下標(biāo)為1至倒數(shù)第2個元素之間的所有元素,規(guī)則:左閉右開 print(test_tuple[1:-1]) # 元組支持單個正數(shù)索引取值: 取正數(shù)第2個元素 print(test_tuple[2]) # 元組支持單個負(fù)數(shù)索引取值: 取倒數(shù)第2個元素 print(test_tuple[-2]) # 元組支持非區(qū)間索引取值: 從倒數(shù)第2個元素一直往前取所有 print(test_tuple[:-1])
output:
[200, 300, 400]
300
400
[100, 200, 300, 400]
********************
(10, 20)
20
20
('jack', 10, 20)
4. 嵌套 & 數(shù)據(jù)類型強(qiáng)轉(zhuǎn)
列表和元組都可以隨意嵌套和數(shù)據(jù)類型轉(zhuǎn)換,見如下示例。
1). 嵌套
input:
# 列表內(nèi)的元素支持嵌套,元素可以是一個列表 test_list = [[100, 200, 300], [400, 500]] print("test_list列表中第1個元素的數(shù)據(jù)類型,{}".format(type(test_list[0]))) # 元組內(nèi)的元素支持嵌套,元素可以是一個元組 test_tuple = (('jack', 10, 20, 'tom'), (4, 5, 6)) print("test_tuple列表中第1個元素的數(shù)據(jù)類型,{}".format(type(test_tuple[0])))
output:
test_list列表中第1個元素的數(shù)據(jù)類型,<class 'list'>
test_tuple列表中第1個元素的數(shù)據(jù)類型,<class 'tuple'>
2). 數(shù)據(jù)類型強(qiáng)轉(zhuǎn)
input:
test_list = [100, 200, 300] print("test_list列表使用tuple()函數(shù)進(jìn)行強(qiáng)轉(zhuǎn)后,元素輸出結(jié)果為:{}".format(tuple(test_list))) print("test_list列表使用tuple()函數(shù)進(jìn)行強(qiáng)轉(zhuǎn)后,元素所屬數(shù)據(jù)類型輸出結(jié)果為:{}".format(type(tuple(test_list)))) print("*" * 60) test_tuple = ('jack', 10, 20, 'tom') print("test_tuple元組使用list()函數(shù)進(jìn)行強(qiáng)轉(zhuǎn)后,元素輸出結(jié)果為:{}".format(list(test_tuple))) print("test_tuple元組使用list()函數(shù)進(jìn)行強(qiáng)轉(zhuǎn)后,元素所屬數(shù)據(jù)類型輸出結(jié)果為:{}".format(type(list(test_tuple))))
output:
test_list列表使用tuple()函數(shù)進(jìn)行強(qiáng)轉(zhuǎn)后,元素輸出結(jié)果為:(100, 200, 300)
test_list列表使用tuple()函數(shù)進(jìn)行強(qiáng)轉(zhuǎn)后,元素所屬數(shù)據(jù)類型輸出結(jié)果為:<class 'tuple'>
************************************************************
test_tuple元組使用list()函數(shù)進(jìn)行強(qiáng)轉(zhuǎn)后,元素輸出結(jié)果為:['jack', 10, 20, 'tom']
test_tuple元組使用list()函數(shù)進(jìn)行強(qiáng)轉(zhuǎn)后,元素所屬數(shù)據(jù)類型輸出結(jié)果為:<class 'list'>
5. 常用內(nèi)置函數(shù)
1). count(item)
表示統(tǒng)計列表 / 元組中 item(元素) 出現(xiàn)的次數(shù)
input:
test_list = [100, 200, 300, 100, 400] test_tuple = ('jack', 10, 20, 'tom', 10, 20, 10) print("test_list列表中統(tǒng)計元素100出現(xiàn)的次數(shù)為:{}".format(test_list.count(100))) print("test_tuple元組中統(tǒng)計元素10出現(xiàn)的次數(shù)為:{}".format(test_tuple.count(10)))
output:
test_list列表中統(tǒng)計元素100出現(xiàn)的次數(shù)為:2
test_tuple元組中統(tǒng)計元素10出現(xiàn)的次數(shù)為:3
2). index(item)
表示返回列表 / 元組中 item(元素) 第一次出現(xiàn)的索引值
input:
test_list = [100, 200, 300, 100, 400] test_tuple = ('jack', 10, 20, 'tom', 10, 20, 10) print("test_list列表中返回元素100第1次出現(xiàn)的索引值為:{}".format(test_list.index(100))) print("test_tuple元組中返回元素10第1次出現(xiàn)的索引值為:{}".format(test_tuple.index(10)))
output:
test_list列表中返回元素100第1次出現(xiàn)的索引值為:0
test_tuple元組中返回元素10第1次出現(xiàn)的索引值為:1
3). list.reverse()
表示原地倒轉(zhuǎn)列表(注意:元組沒有這個內(nèi)置函數(shù))
input:
test_list = [100, 200, 300, 100, 400] test_list.reverse() print("test_list列表原地倒轉(zhuǎn)后返回元素為:{}".format(test_list))
output:
test_list列表原地倒轉(zhuǎn)后返回元素為:[400, 100, 300, 200, 100]
4). list.sort()
表示排序列表(注意:元組沒有這個內(nèi)置函數(shù))
input:
test_list = [100, 200, 300, 100, 400] test_list.sort() print("test_list列表原地倒轉(zhuǎn)后返回元素為:{}".format(test_list))
output:
test_list列表原地倒轉(zhuǎn)后返回元素為:[100, 100, 200, 300, 400]
6. 存儲方式
PS: 以下示例使用的是 Python3.9版本
input:
test_list = [100, 200, 300] print("初始化相同元素,列表所占用的大小為:{}".format(test_list.__sizeof__())) test_tuple = (100, 200, 300) print("初始化相同元素,元組所占用的大小為:{}".format(test_tuple.__sizeof__()))
output:
初始化相同元素,列表所占用的大小為:104
初始化相同元素,元組所占用的大小為:48
從輸出結(jié)果可以看到,初始化相同元素,但是元組的存儲空間,卻比列表要少56字節(jié),這是由于什么原因?qū)е碌哪兀?/p>
1). 存儲指針占用:8字節(jié)
因?yàn)榱斜硎莿討B(tài)的,所以它需要存儲指針,來指向?qū)?yīng)的元素(上述例子中,對于int型,存儲指針占用:8字節(jié))
2). 分配8字節(jié)長度用于追蹤列表空間使用情況
由于列表可變,所以需要額外存儲已經(jīng)分配的長度大小:8字節(jié),用于實(shí)時追蹤列表空間的使用情況,當(dāng)空間不足時,及時分配額外空間
3). 預(yù)留3個元素的存儲空間共24字節(jié)
因?yàn)榱斜硎莿討B(tài)的,需要提前預(yù)留3個元素的存儲空間,每個元素是8字節(jié),可以大大節(jié)省頻繁分配空間的開銷
4). 空列表占用空間比空元組占用空間多16字節(jié)
空列表所占用的大小為:40字節(jié),空元組所占用的大小為:24字節(jié)
所以,最終列表比元組多占用的 56字節(jié) = 8字節(jié) + 8字節(jié) + 24字節(jié) + 16字節(jié)
PS:
元組長度大小固定,元素不可變,所以存儲空間固定,空元組占用24字節(jié),在初始化3個元素時,每個元素占用8字節(jié),最終共占用48字節(jié)。
從上面的示例可知,元組要比列表更加輕量級一些,所以總體上而言,元組的性能速度要略優(yōu)于列表。
到此這篇關(guān)于深入剖析Python的列表和元組的文章就介紹到這了,更多相關(guān)Python的列表和元組內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
零基礎(chǔ)寫python爬蟲之使用Scrapy框架編寫爬蟲
前面的文章我們介紹了Python爬蟲框架Scrapy的安裝與配置等基本資料,本文我們就來看看如何使用Scrapy框架方便快捷的抓取一個網(wǎng)站的內(nèi)容,隨便選個小站(dmoz.org)來示例吧2014-11-11python游戲?qū)崙?zhàn)項(xiàng)目之童年經(jīng)典超級瑪麗
史上十大最經(jīng)典小霸王游戲中魂斗羅只能排在第二,那么第一是誰?最經(jīng)典最風(fēng)靡的當(dāng)屬超級瑪麗,那個戴帽子的大胡子穿著背帶褲的馬里奧哪個不認(rèn)得,小編帶你用python實(shí)現(xiàn)超級瑪麗緬懷童年2021-09-09Python?pandas替換指定數(shù)據(jù)的方法實(shí)例
在處理數(shù)據(jù)的時候,很多時候會遇到替換的情況,下面這篇文章主要給大家介紹了關(guān)于Python?pandas替換指定數(shù)據(jù)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-07-07基于Python Numpy的數(shù)組array和矩陣matrix詳解
下面小編就為大家分享一篇基于Python Numpy的數(shù)組array和矩陣matrix詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-04-04Python 游戲大作炫酷機(jī)甲闖關(guān)游戲爆肝數(shù)千行代碼實(shí)現(xiàn)案例進(jìn)階
本篇文章給大家?guī)鞵ython的一個游戲大制作—機(jī)甲闖關(guān)冒險,數(shù)千行代碼實(shí)現(xiàn)的游戲,過程很詳細(xì),對大家的學(xué)習(xí)或工作具有一定的借鑒價值,需要的朋友可以參考下2021-10-10Django 實(shí)現(xiàn)對已存在的model進(jìn)行更改
這篇文章主要介紹了Django 實(shí)現(xiàn)對已存在的model進(jìn)行更改,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-03-03python+selenium+chromedriver實(shí)現(xiàn)爬蟲示例代碼
這篇文章主要介紹了python+selenium+chromedriver實(shí)現(xiàn)爬蟲示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04