列表推導(dǎo)式
Python里面有個(gè)很棒的語法糖(syntactic sugar),它就是 list comprehension ,有人把它翻譯成“列表推導(dǎo)式”,也有人翻譯成“列表解析式”。名字聽上去很難理解,但是看它的語法就很清晰了。雖然名字叫做 list comprehension,但是這個(gè)語法同樣適用于dict、set等這一系列可迭代(iterable)數(shù)據(jù)結(jié)構(gòu)。
語法規(guī)范:
其中的 if 條件判斷根據(jù)需要可有可無。 下面看一個(gè)具體的例子,生成一個(gè)包含10以內(nèi)的偶數(shù)的list:
由for循環(huán)升級到列表推導(dǎo)式: 在沒有了解 list comprehension 之前,上面那個(gè)生成偶數(shù)list的通常做法是用 for 循環(huán):
很明顯, for 循環(huán)占用了4行代碼,而 list comprehension 只用了1行代碼。 文章開始說到推導(dǎo)式的語法規(guī)范時(shí),我們講了 if 表達(dá)式是可有可無的,這也符合我們編程遇到的實(shí)際情況。比如,要生成一個(gè)10以內(nèi)的整數(shù)的平方的列表:
復(fù)雜的嵌套循環(huán) 我們先來看一個(gè)例子,把一個(gè)矩陣(以列表為元素的列表)展平為一個(gè)列表。首先,我們用 for 循環(huán)來實(shí)現(xiàn)一下:
接著我們用列表推導(dǎo)式實(shí)現(xiàn)該功能:
還是一行代碼就搞定,但一行里面有兩個(gè) for ,看起來很亂,兩個(gè) for ,哪個(gè)在前哪個(gè)在后呢?只要記住他們的順序和不用推導(dǎo)式的原始for循環(huán)是一致的即可。 推導(dǎo)式的可讀性 一行代碼搞定幾行代碼的事情,看上去很簡潔,但是讀起來很費(fèi)勁,尤其是當(dāng)條件語句很長的時(shí)候,把這一行代碼變得很長,超過了代碼規(guī)范規(guī)定的長度(一般是80個(gè)字符),也使得理解代碼變得困難。
面對一行長長的代碼該如何下口讀,如何理解呢?別著急,好在Python允許在中括號、花括號之間斷行: 列表推導(dǎo)式的斷行: 斷行前:
斷行后:
帶嵌套循環(huán)的推導(dǎo)式的斷行: 斷行前:
斷行后:
字典(dict)和集合(set)的推導(dǎo)式 前面我們也提到過,推導(dǎo)式不僅僅適用于列表,它同樣使用于字典dict和集合set。 把一個(gè)字典的key和value互換:
用一個(gè)列表的所有單詞的首字母生成一個(gè)集合:
通過以上講解就可以輕松掌握Python的列表推導(dǎo)式( list comprehension )了,簡而言之,就是把普通的多行for循環(huán)壓縮成一行代碼,這種壓縮語法適用于列表、字典、集合等可迭代數(shù)據(jù)結(jié)構(gòu)(iterables)。
深淺拷貝
對象引用、淺拷貝、深拷貝(拓展、難點(diǎn)、重點(diǎn)) Python中,對象的賦值,拷貝(深/淺拷貝)之間是有差異的,如果使用的時(shí)候不注意,就可能產(chǎn)生意外的結(jié)果
其實(shí)這個(gè)是由于共享內(nèi)存導(dǎo)致的結(jié)果
拷貝:原則上就是把數(shù)據(jù)分離出來,復(fù)制其數(shù)據(jù),并以后修改互不影響。 先看 一個(gè)非拷貝的例子
使用=賦值(對象引用)
=賦值:數(shù)據(jù)完全共享 =賦值是在內(nèi)存中指向同一個(gè)對象,如果是可變(mutable)類型,比如列表,修改其中一個(gè),另一個(gè)必定改變
如果是不可變類型 (immutable) ,比如字符串,修改了其中一個(gè),另一個(gè)并不會變
淺拷貝(copy)
淺拷貝:數(shù)據(jù)半共享(復(fù)制其數(shù)據(jù)獨(dú)立內(nèi)存存放,但是只拷貝成功第一層)
深拷貝(deepcopy)
深拷貝:數(shù)據(jù)完全不共享(復(fù)制其數(shù)據(jù)完完全全放獨(dú)立的一個(gè)內(nèi)存,完全拷貝,數(shù)據(jù)不共享)
深拷貝就是完完全全復(fù)制了一份,且數(shù)據(jù)不會互相影響,因?yàn)閮?nèi)存不共享。 深拷貝的方法有
總結(jié):
copy.copy 淺拷貝 只拷貝父對象,不會拷貝對象的內(nèi)部的子對象。 copy.deepcopy 深拷貝 拷貝對象及其子對象
|