Python 編碼
-
Unicode把所有語言都統(tǒng)一到一套編碼里,這樣就不會再有亂碼問題了。如果統(tǒng)一成Unicode編碼,亂碼問題從此消失了。但是,如果文本基本上全部是英文的話,用Unicode編碼比ASCII編碼需要多一倍的存儲空間,在存儲和傳輸上就十分不劃算。所以,本著節(jié)約的精神,又出現(xiàn)了把Unicode編碼轉(zhuǎn)化為“可變長編碼”的UTF-8編碼。UTF-8編碼把一個Unicode字符根據(jù)不同的數(shù)字大小編碼成1-6個字節(jié),常用的英文字母被編碼成1個字節(jié),漢字通常是3個字節(jié),只有很生僻的字符才會被編碼成4-6個字節(jié)。如果你要傳輸?shù)奈谋景罅坑⑽淖址肬TF-8編碼就能節(jié)省空間。
-
在計算機(jī)內(nèi)存中,統(tǒng)一使用Unicode編碼,當(dāng)需要保存到硬盤或者需要傳輸?shù)臅r候,就轉(zhuǎn)換為UTF-8編碼。用記事本編輯的時候,從文件讀取的UTF-8字符被轉(zhuǎn)換為Unicode字符到內(nèi)存里,編輯完成后,保存的時候再把Unicode轉(zhuǎn)換為UTF-8保存到文件。
-
在最新的Python 3版本中,字符串是以Unicode編碼的,也就是說,Python的字符串支持多語言,
-
對于單個字符的編碼,Python提供了ord()函數(shù)獲取字符的整數(shù)編碼表示,chr()函數(shù)把編碼轉(zhuǎn)換為對應(yīng)的字符。
List
-
Python內(nèi)置的一種數(shù)據(jù)類型是列表:list。list是一種有序的集合,可以隨時添加和刪除其中的元素。
-
當(dāng)索引超出了范圍時,Python會報一個IndexError錯誤,如果要取最后一個元素,除了計算索引位置外,還可以用-1做索引,直接獲取最后一個元素.
-
insert(index,元素)可以把元素插入到指定的位置,該位置及其后的元素會往后移動一位
tuple
-
另一種有序列表叫元組:tuple。tuple和list非常類似,但是tuple一旦初始化就不能修改,比如同樣是列出同學(xué)的名字.
-
要定義一個只有1個元素的tuple;如果你這么定義t = (1); 定義的不是tuple,是1這個數(shù)!這是因?yàn)槔ㄌ?)既可以表示tuple,又可以表示數(shù)學(xué)公式中的小括號,這就產(chǎn)生了歧義,因此,Python規(guī)定,這種情況下,按小括號進(jìn)行計算,計算結(jié)果自然是1。所以,只有1個元素的tuple定義時必須加一個逗號,,來消除歧義t = (1,)。
-
tuple的不變指的是引用不變,比如里面存的是對象,改變對象的某些屬性,但這個對象沒有變,即tuple的元素未變。
dict
-
Python內(nèi)置了字典:dict的支持,dict全稱dictionary,在其他語言中也稱為map,使用鍵-值(key-value)存儲,具有極快的查找速度。
-
為什么dict查找速度這么快?因?yàn)閐ict的實(shí)現(xiàn)原理和查字典是一樣的。假設(shè)字典包含了1萬個漢字,我們要查某一個字,一個辦法是把字典從第一頁往后翻,直到找到我們想要的字為止,這種方法就是在list中查找元素的方法,list越大,查找越慢。第二種方法是先在字典的索引表里(比如部首表)查這個字對應(yīng)的頁碼,然后直接翻到該頁,找到這個字。無論找哪個字,這種查找速度都非常快,不會隨著字典大小的增加而變慢。dict就是第二種實(shí)現(xiàn)方式,給定一個名字,比如'Michael',dict在內(nèi)部就可以直接計算出Michael對應(yīng)的存放成績的“頁碼”,也就是95這個數(shù)字存放的內(nèi)存地址,直接取出來,所以速度非常快。
set
-
集合(set)是一個無序的不重復(fù)元素序列。
-
可以使用大括號 { } 或者 set() 函數(shù)創(chuàng)建集合,注意:創(chuàng)建一個空集合必須用 set() 而不是 { },因?yàn)?{ } 是用來創(chuàng)建一個空字典。
-
創(chuàng)建格式:parame = {value01,value02,...} 或者 set(value)
函數(shù)
函數(shù)的參數(shù)
-
位置參數(shù),power(x, n)函數(shù)有兩個參數(shù):x和n,這兩個參數(shù)都是位置參數(shù),調(diào)用函數(shù)時,傳入的兩個值按照位置順序依次賦給參數(shù)x和n。
-
默認(rèn)參數(shù),設(shè)置有默認(rèn)值的參數(shù)
-
可變參數(shù),定義可變參數(shù)和定義一個list或tuple參數(shù)相比,僅僅在參數(shù)前面加了一個*號。在函數(shù)內(nèi)部,參數(shù)numbers接收到的是一個tuple,因此,函數(shù)代碼完全不變。但是,調(diào)用該函數(shù)時,可以傳入任意個參數(shù),包括0個參數(shù)。如def calc(*numbers):
-
關(guān)鍵字參數(shù),可變參數(shù)允許你傳入0個或任意個參數(shù),這些可變參數(shù)在函數(shù)調(diào)用時自動組裝為一個tuple。而關(guān)鍵字參數(shù)允許你傳入0個或任意個含參數(shù)名的參數(shù),這些關(guān)鍵字參數(shù)在函數(shù)內(nèi)部自動組裝為一個dict。如def person(name, age, **kw):
迭代
- 判斷一個對象是可迭代對象。方法是通過collections模塊的Iterable類型判斷
from collections import Iterable
isinstance('abc', Iterable) # str是否可迭代
- 如果要對list實(shí)現(xiàn)類似Java那樣的下標(biāo)循環(huán)。Python內(nèi)置的enumerate函數(shù)可以把一個list變成索引-元素對,這樣就可以在for循環(huán)中同時迭代索引和元素本身
for i, value in enumerate(['A', 'B', 'C']):
print(i, value)
列表生成式
-
列表生成式即List Comprehensions,是Python內(nèi)置的非常簡單卻強(qiáng)大的可以用來創(chuàng)建list的生成式。
-
如果要生成[1x1, 2x2, 3x3, ..., 10x10]怎么做?方法一是循環(huán):
>>> L = []
>>> for x in range(1, 11):
... L.append(x * x)
...
>>> L
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
- 但是循環(huán)太繁瑣,而列表生成式則可以用一行語句代替循環(huán)生成上面的list:寫列表生成式時,把要生成的元素x * x放到前面,后面跟for循環(huán),就可以把list創(chuàng)建出來,十分有用,多寫幾次,很快就可以熟悉這種語法。
>>> [x * x for x in range(1, 11)]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
- for循環(huán)后面還可以加上if判斷,這樣我們就可以篩選出僅偶數(shù)的平方:
>>> [x * x for x in range(1, 11) if x % 2 == 0]
[4, 16, 36, 64, 100]
- 還可以使用兩層循環(huán),可以生成全排列:
>>> [m + n for m in 'ABC' for n in 'XYZ']
['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']
生成器
-
如果列表元素可以按照某種算法推算出來,那我們是否可以在循環(huán)的過程中不斷推算出后續(xù)的元素呢?這樣就不必創(chuàng)建完整的list,從而節(jié)省大量的空間。在Python中,這種一邊循環(huán)一邊計算的機(jī)制,稱為生成器:generator。
-
要創(chuàng)建一個generator,有很多種方法。第一種方法很簡單,只要把一個列表生成式的[]改成(),就創(chuàng)建了一個generator:
>>> L = [x * x for x in range(10)]
>>> L
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> g = (x * x for x in range(10))
>>> g
at 0x1022ef630>
-
可以通過next()函數(shù)獲得generator的下一個返回值,generator保存的是算法,每次調(diào)用next(g),就計算出g的下一個元素的值,直到計算到最后一個元素,沒有更多的元素時,拋出StopIteration的錯誤。
-
當(dāng)然,不斷調(diào)用next(g)實(shí)在是太變態(tài)了,正確的方法是使用for循環(huán),因?yàn)間enerator也是可迭代對象:
>>> g = (x * x for x in range(10))
>>> for n in g:
... print(n)
- 如果一個函數(shù)定義中包含yield關(guān)鍵字,那么這個函數(shù)就不再是一個普通函數(shù),而是一個generator,如
def fib(max):
n, a, b = 0, 0, 1
while n < max:
yield b
a, b = b, a + b
n = n + 1
return 'done'
- 這里,最難理解的就是generator和函數(shù)的執(zhí)行流程不一樣。函數(shù)是順序執(zhí)行,遇到return語句或者最后一行函數(shù)語句就返回。而變成generator的函數(shù),在每次調(diào)用next()的時候執(zhí)行,遇到y(tǒng)ield語句返回,再次執(zhí)行時從上次返回的yield語句處繼續(xù)執(zhí)行。
迭代器
-
凡是可以被next()函數(shù)調(diào)用并不斷返回下一個值的對象稱為迭代器:Iterator。
-
凡是可作用于for循環(huán)的對象都是Iterable類型;
-
可以使用isinstance()判斷一個對象是否是Iterator對象
-
生成器都是Iterator對象,但list、dict、str雖然是Iterable,卻不是Iterator。
-
把list、dict、str等Iterable變成Iterator可以使用iter()函數(shù)
-
為什么list、dict、str等數(shù)據(jù)類型不是Iterator?這是因?yàn)镻ython的Iterator對象表示的是一個數(shù)據(jù)流,Iterator對象可以被next()函數(shù)調(diào)用并不斷返回下一個數(shù)據(jù),直到?jīng)]有數(shù)據(jù)時拋出StopIteration錯誤。可以把這個數(shù)據(jù)流看做是一個有序序列,但我們卻不能提前知道序列的長度,只能不斷通過next()函數(shù)實(shí)現(xiàn)按需計算下一個數(shù)據(jù),所以Iterator的計算是惰性的,只有在需要返回下一個數(shù)據(jù)時它才會計算。Iterator甚至可以表示一個無限大的數(shù)據(jù)流,例如全體自然數(shù)。而使用list是永遠(yuǎn)不可能存儲全體自然數(shù)的。
-
Python的for循環(huán)本質(zhì)上就是通過不斷調(diào)用next()函數(shù)實(shí)現(xiàn)的
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
