列表和列表的內(nèi)存處理
列表是python組合數(shù)據(jù)類型中使用較多的類型之一,以其對(duì)批量數(shù)據(jù)提供友好的訪問支持而被廣大開發(fā)人員鐘愛
在程序開發(fā)過程中飞涂,對(duì)于列表的操作有兩種不同的情況需要考慮:
1旦部、我們需要一個(gè)存放了大量的有規(guī)律的數(shù)據(jù)的列表祈搜,這個(gè)列表怎么定義
2、列表中存儲(chǔ)的數(shù)據(jù)量過大士八,會(huì)不會(huì)對(duì)內(nèi)存產(chǎn)生影響
第一個(gè)問題:
我們需要一個(gè)存放了大量的有規(guī)律的數(shù)據(jù)的列表容燕,這個(gè)列表怎么定義?
解決方法:列表的聲明推導(dǎo)式
推導(dǎo)式:按照一定的規(guī)則進(jìn)行推導(dǎo)產(chǎn)生對(duì)應(yīng)的數(shù)據(jù)
語法:變量 = [推導(dǎo)表達(dá)式]
例如:
添加一個(gè)0~20的自然數(shù)序列
my = [x for x in range(0, 20)]
輸出結(jié)果:
附帶條件的列表推導(dǎo)式:取偶數(shù)
my2= [x for x in range(0, 20) if x % 2 == 0]
輸出結(jié)果:
附帶運(yùn)算的列表推導(dǎo)式:求平方
my3 = [x**2 for x in range(0, 10)]
輸出結(jié)果:
附帶多項(xiàng)數(shù)據(jù)的列表推導(dǎo)式:兩個(gè)列表的相加
my4= [x + y for x in range(0, 5) for y in range(0,2)]
輸出結(jié)果:
列表的推導(dǎo)式的優(yōu)缺點(diǎn):
優(yōu)點(diǎn):語法簡(jiǎn)單曹铃,可以通過包含邏輯條件生成一個(gè)符合條件的列表
缺點(diǎn):邏輯過于簡(jiǎn)單缰趋,不能生成條件更加復(fù)雜的更加準(zhǔn)確的列表
第二個(gè)問題:
列表中存儲(chǔ)的數(shù)據(jù)量過大,會(huì)不會(huì)對(duì)內(nèi)存產(chǎn)生影響陕见? 會(huì)導(dǎo)致對(duì)內(nèi)存的大量消耗
兩個(gè)方面:
沒有規(guī)律的大量數(shù)據(jù):
解決方案:不要放在列表中秘血,放在數(shù)據(jù)庫等中,通過列表每次讀取一小部分评甜,處理完繼續(xù)讀取
有規(guī)律的大量數(shù)據(jù):
解決方案:不要直接通過列表操作灰粮,而是通過列表生成器操作
生成器:在程序執(zhí)行運(yùn)算到該代碼時(shí),才會(huì)執(zhí)行運(yùn)算得到結(jié)果
生成器語法結(jié)構(gòu)和推導(dǎo)式語法結(jié)構(gòu)及其類似
一個(gè)基本生成器:
生成 0~10 自然數(shù)序列的數(shù)據(jù)
my_generator = (x for x in range(0, 10))
輸出結(jié)果:產(chǎn)生一個(gè)object對(duì)象
推導(dǎo)式與生成器的區(qū)別:
推導(dǎo)式:直接產(chǎn)生包含所有數(shù)據(jù)的列表
生成器:產(chǎn)生了一個(gè)生成器對(duì)象忍坷,包括算法
使用生成器中的數(shù)據(jù):
方法一:
通過系統(tǒng)內(nèi)建函數(shù)next()獲取生成器中下一個(gè)數(shù)據(jù)
print(next(my_generator)) #輸出結(jié)果: 0
print(next(my_generator)) #輸出結(jié)果: 1
print(next(my_generator)) #輸出結(jié)果: 2
print(next(my_generator)) #輸出結(jié)果: 3
方法二:
通過類型的next()魔法方法粘舟,直接獲取下一個(gè)數(shù)據(jù)(接著上一個(gè)數(shù)據(jù)繼續(xù)往下輸出)
print(my_generator.__next__()) #輸出結(jié)果: 4
print(my_generator.__next__()) #輸出結(jié)果: 5
print(my_generator.__next__()) #輸出結(jié)果: 6
print(my_generator.__next__()) #輸出結(jié)果: 7
總結(jié):
列表生成器是對(duì)與列表推導(dǎo)式以及列表本身進(jìn)行的極度的優(yōu)化
列表生成器中的表達(dá)式與列表推導(dǎo)式中的表達(dá)式功能相同
遇到少量數(shù)據(jù)的時(shí)候用列表處理,大量數(shù)據(jù)用列表生成器處理
迭代器:
什么是迭代對(duì)象:
collections.Iterable 迭代對(duì)象
程序中任何可以通過next()操作的對(duì)象或者可以通過for循環(huán)遍歷的對(duì)象都是迭代對(duì)象
什么是迭代標(biāo)識(shí):
collections.Iterator 迭代標(biāo)識(shí)
迭代對(duì)象中有一個(gè)迭代標(biāo)識(shí)佩研,迭代標(biāo)識(shí)可以通過迭代對(duì)象中的iter()函數(shù)方法獲得
迭代標(biāo)識(shí)就是每一次迭代的過程中柑肴,來記錄當(dāng)前運(yùn)行到第幾步了的標(biāo)識(shí)
迭代器:
在迭代的過程中,迭代對(duì)象加上迭代標(biāo)識(shí)合起來被稱為迭代器
迭代器包含了可迭代對(duì)象旬薯,可迭代標(biāo)識(shí)
問題:
迭代器和生成器之間的區(qū)別:
迭代器:
PYTHON中在collections集合模塊中提供了迭代器對(duì)象
迭代器由兩部分組成:
迭代對(duì)象:collections.Iterable
用于循環(huán)遍歷的迭代對(duì)象晰骑,它是一個(gè)Iterable類型的對(duì)象,
迭代標(biāo)識(shí):collections.Iterator
用于記錄迭代狀態(tài)的迭代標(biāo)識(shí)绊序,通過Iterator對(duì)象進(jìn)行操作
生成器:
PYTHON中提供的一種可以將程序算法表達(dá)式包含起來的一個(gè)用于產(chǎn)生列表數(shù)據(jù)的對(duì)象
在操作過程中通過next()函數(shù)進(jìn)行調(diào)用硕舆,算法表達(dá)式產(chǎn)生下一個(gè)數(shù)據(jù)用于程序運(yùn)算的操作對(duì)象
迭代器:用來遍歷數(shù)據(jù)
生成器:用來產(chǎn)生數(shù)據(jù)
生成器:用來創(chuàng)建一個(gè)對(duì)象,包含一個(gè)表達(dá)式骤公,推導(dǎo)一個(gè)數(shù)據(jù)
迭代器:用于對(duì)可迭代對(duì)象循環(huán)遍歷
自定義類型的對(duì)象來完成可迭代操作:
我們可以在自定義類型中抚官,通過重寫iter()方法,讓自定義對(duì)象返回一個(gè)迭代器對(duì)象阶捆,這樣也就可以讓自定義類型的對(duì)象來完成可迭代操作
class Person:
def __init__(self, fav):
self.fav = fav
def __iter__(self):
print("獲取迭代對(duì)象的函數(shù)被執(zhí)行了")
return iter(self.fav)
p = Person(["路明非", "楚子航", "凱撒", "芬格爾"])
for x in p:
print(x)
輸出結(jié)果:
思考題:
- list/set/dict/tuple是否是Iterable類型凌节,是否是Iterator類型
Iterable類型?否
Iterator類型洒试?否 - [1,2,3]是否是Iterable類型刊咳,是否是Iterator類型
Iterable類型?是
Iterator類型儡司?否 - class User:..是否是Iterable類型娱挨,是否是Iterator類型
Iterable類型?否[如果類型重寫了iter()函數(shù)并返回了迭代對(duì)象:是]
Iterator類型捕犬?否 - 什么是迭代器跷坝?
迭代器是用來標(biāo)識(shí)一個(gè)對(duì)象是否可以循環(huán)遍歷酵镜,并且可以記錄循環(huán)遍歷狀態(tài)的對(duì)象
主要通過collections.Iterable類型來判斷是否是可以迭代的類型
在迭代過程中,通過collections.Iterator來記錄迭代狀態(tài)
如有錯(cuò)誤柴钻,敬請(qǐng)指出淮韭!