天天看點

python基礎知識

1、print()函數

print函數用于向控制台、python解釋器、cmd指令行輸出你想要輸出的内容。print函數有輸入參數,可以是字元串、數字、變量等等,也可以是它們的混合,不同對象之間可以使用,來分隔,print函數遇到,的時候會輸出一個空格來作為分隔輸出的效果。注意:在print函數中,如果輸入的内容是可以繼續計算或者合并的,那麼python會先計算或者合并之後再輸出。

如:

print(100+200)

print('a'+'b')

會輸出數字300以及字元串'ab'

2、input()函數

用于從指令行、python解釋器擷取使用者的輸入,從subline text中無法輸入。使用者的所有輸入都會被當做是str類型,即字元串類型,使用者可以将input的輸入内容放入變量中,即:name=input()用于儲存輸入的内容用作後續代碼的指代。同時,為了更友好的界面,可以給input函數輸入參數值,參數值可以是一個字元串,也可以是一個變量的指代,用于在提示使用者輸入的時候給出詳細的說明,即:name=input('inpurt your name:')或者i='please input here:'   ,  name=input(變量i)。

3、組織方式

python的組織方式是通過統一縮進,主旨是簡潔優雅。

4、資料類型和變量

====整數和浮點數:

整數分為正整數、負整數、0

浮點數有精度問題,很大的浮點數可以用科學計數法标記,其中的10使用e來表示,即:12300000 =  1.23e7 ,或者類似2.35e-5等等

====字元串:

字元串,顧名思義,是一串字元序列,使用單引号或者雙引号包括起來,外圍的單引号或者雙引号不算字元串的内容。

如果字元串内容有單引号,那麼外圍要使用雙引号包圍,反之亦然,如果字元串内容中既有單引号又有雙引号,則要使用\來轉義其中一個引号

如:' i\'am  a "good" man  ' ,使用\'來表示轉義單引号

====字元串+轉義字元:

在print函數中無法通過回車來展現最終列印字元串的換行,必須使用\n來表示換行,使用\t表示制表符,\單引号或者雙引号,\\表示\符号

注意:預設情況下,一個字元串中的\轉義字元是會轉義的,轉義規則根據上述說明。但是如果在字元串前面加上r,則表示不對字元串内容做轉義

預設轉義,print('line1\'line2')---->line1'line2

強制不轉義,print(r'line1\'line2')----->line1\'line2(可用于re的過濾規則中)

這種情況下,不會轉義:print('line1\\'+'nline2')------>line1\nline2

====字元串+''''''實作簡化換行:

如果要輸出一個段落,涉及字元串内部的多處換行,可以使用\n來實作,也可以使用print('''  ''')來實作,裡面的字元串根據實際内容直接回車

print('''

這裡是根據傳入的頁數,形成了所有的連結

這裡是server端

這是一張新圖檔,準備下載下傳

''')

====布爾值:

True和False,用于各種判斷,意味着一件事件為真或者為假,如3>2為真,2==0為假

邏輯運算and,or,not,邏輯運算會與布爾值結合計算,如True  and  True 的結果為True

注意:在python中,1可以被認為是True,0被認為是False(可以計算),其他值即不是True也不是False

注意is是表示兩邊是同一個對象

====空值:

python中的空值使用None表示,注意,None不是0,對于0而言是有意義的,而None是一種特殊的屬性,意味着空

====變量:

python支援多種資料類型,有内置原生資料類型,也有自定義擴充資料類型,任何類型的資料都可以看成一個對象,通過變量來指向它,對變量進行指派就是讓某一個變量指向某一個對象,建立他們兩之間的關系。

變量類似一個指針,指向某一個記憶體對象,python是動态語言,是以可以指向不同類型的對象,如str,int,float,list等等,java是靜态語言一旦int  a,那麼a隻能指向ini類型對象

a='hello' , b=a ,意味着把a指向的對象的位址賦給b,或者說,讓b指向a所指向的對象,這時候'hello'對象有兩個指向自己的指針。如果此時a='world',那麼print(b)還是等于'hello'

====常量:

約定俗成的使用全部大寫變量名來表示常量,如PI

對于除法/,python3中是不會取整的,python2是取整的

對于地闆除//,python3和2都是取整的

使用%擷取餘數

5、字元串編碼問題

====曆史:

在計算機曆史上,計算機被設計成擁有處理數字的功能,計算機底層1個位元組定義成8個位,1個位元組可以表示的數字最大是255,如果需要表示更大的數字,就需要更多的位元組,2個位元組可以表示最大65535,4個位元組可以表示42億左右。根據計算機的原本設計是隻能處理數字,如果要處理文本,即處理字元串,則需要把字元串與數字進行映射,即通過編碼的方式記錄每一個字元對應的數字。計算機是美國人發明的,是以當時隻需要處理英文字元串,所有英文字元,包括字母大小寫、數字、符号等等加在一起一共形成了127個字元,這127個字元通過1個位元組就可以完全表示。通過1個位元組對應的1個整數,映射到不同的字元,這種編碼方式就是ASCII編碼方式。

随着計算機的發展,不同國家都在使用,都想通過計算機輸入本國的語言,如中文,對于中文而言,中文的字元至少需要2個位元組即至少需要65535個數字才能表示,是以中國為中文定制了GB2312編碼方式,用于将中文編碼到計算機的底層整數。同樣的,不同國家有不同的編碼方式,這就導緻:同樣的1個編碼整數可能會在不同國家有不同的表示,而且,如果多個國家的程式放在一起,計算機就無法識别某一個字元串是屬于英文還是中文還是其他國家的字元。

為了解決不同國家定制不同的編碼标準,出現了unicode統一字元編碼标準,unicode标準常常使用2個位元組表示1個字元,将世界上所有的語言都包含到這個編碼标準中,這樣不論計算機在哪裡使用,不論計算機使用的是哪種語言,都不會出現混亂和沖突的問題。對于一些生僻的字元,unicode可能需要使用4-6個字元來表示。

而如果單純隻使用unicode編碼的時候,會出現空間浪費的問題,如果程式全部使用英文編寫,所有英文字元預設2個unicode位元組對應1個英文字元。是以使用unicode雖然可以很好的解決不同語言之間互通的問題,但是會帶來空間浪費和效率不高的問題。

這時候就需要使用UTF-8可變長編碼方式,使用UTF-8的時候,如果是中文就是2個位元組對應1個中文字元,如果是英文就是1個位元組對應1個英文字元,即UTF-8的位元組使用數量是根據實際使用的語言來靈活變化的,這種好處尤其展現在資料的儲存、壓縮、傳輸上。是以現在的計算機儲存的資料都是UTF-8編碼方式,一旦被程式調用的時候,檔案中的資料則轉換成unicode編碼方式在記憶體中被處理,在處理完畢再次儲存之前又被轉換成高效的UTF-8編碼方式。

我們從網站上擷取網頁的時候,網頁html是以源代碼的形式傳回給我們的浏覽器,源代碼中經常有:<meta charset="utf-8" /> 表示該網頁使用UTF-8編碼的方式來傳輸資料。

====python字元串的編碼:

python3版本中,所有的字元串str類型對象都是使用unicode編碼方式,即python中的所有字元串,都有對應的unicode整數,如:

unicode是針對每一個字元做編碼的,可以通過ord()函數對任意一個字元求出對應的unicode整數,也可以通過chr()輸入unicode整數來得到對應的unicode字元

當然,也可以這樣寫:'\uxxxx'其中要放入unicode整數的十六進制數,如,25991的十六進制數是0x6587:

====編碼轉換:

python在記憶體中的資料都是unicode編碼,都是str類型的對象。而資料在儲存或者網絡傳輸的時候,必須轉換成byte類型的位元組流的形式,把unicode轉換成byte類型需要依據不同的内容做不同的編碼,所有byte類型的對象都是b開頭,如:

'abc'是str類型的對象,是unicode編碼,是英文,是以轉換成可傳輸的位元組流就是'abc'.encode('ascii')---->b'abc',此時ascii編碼中,1個位元組對應1個英文字元

'中文'是str類型的對象,是unicode編碼,是中文,是以轉換成可傳輸的位元組流就是'中文'.encode('utf-8')---->b'\xe4\xb8\xad\xe6\x96\x87',此時utf-8編碼中,使用3個位元組表示1個中文字元

------------------------------------------------------------------------------------------------------'中文'.encode('gb2312')---->b'\xd6\xd0\xce\xc4' ,此時gb2312編碼中,使用2個字元表示1個中文字元

總結:在計算機記憶體中,在python3中,所有str對象都是unicode編碼,這是為了使不同國家語言可以互通,unicode編碼一般是2個位元組編碼1個字元。而在傳輸、儲存資料的時候,需要把unicode編碼的字元轉換成其他的編碼方式,英文可以轉換成ascii或者utf-8,中文可以轉換成gb2312或者utf-8,變成可傳輸的位元組流。使用不同的編碼方式,1個字元使用的位元組數量不同。

一般情況下,我們都使用unicode和utf-8這兩種,因為中文和英文都可以使用utf-8方式編碼。即:

str對象.encode('utf-8')可以變成位元組流byte類型對象以b開頭,    

byte對象.decode('utf-8')可以變成unicode字元的str類型對象用于計算機和程式的處理,

是以在hello.py檔案的開頭都有:#coding:utf-8就是告訴python解釋器:使用utf-8編碼方式來decode到unicode來處理,然後将unicode的資料encode到utf-8來儲存和傳輸

====python的格式化字元串:

last=72

today=85

rate=(today-last)/last

print('小明的成績從去年的%d分提升到了今年的%d分,增長百分比是:%.1f%%'   %(last,today,rate))

6、list和tuple

====list的性質:

list是python的内置資料類型,翻譯成清單或者數組。list是一組資料或者一組對象或者一組元素的序列,同樣的元素不同的排列是不同的清單。清單的元素數量可以通過len(a)來獲得,list是可變長數組,可以随時通過append在末尾增加元素,通過pop(i)彈出位置i的元素預設是末尾,通過insert(i,xx)在位置i插入xx元素。除此之外,list還是混合類型數組,即數組内部可以允許不同類型的元素,如:a=[1,True,'abc',2.2],此時的a是一個指向一個list位址的變量(性質上是指針)。list通過下标0~len-1的範圍來擷取每一個元素。list可以通過-1,-2來從尾部開始擷取元素,-1表示倒數第1個元素,-2表示倒數第2個元素,以此類推。list中可以放任何類型的對象,除了python内置的整數、浮點數、布爾值、字元串等,還可以是list,tuple,dict,其他自定義資料類型等等。如果list中還有一個list,則意味着内部的list是一個二維數組,如果内部list的一個對象還是一個list,則最内部list是三維數組,以此類推,通過a[1][2]來擷取二維數組的元素。

====tuple的性質:

tuple的性質和list很相似,最大的不同在于tuple更嚴格、更安全、資料隻能取不能增删改,即tuple一旦初始化後則無法改變内容,而list可以随時增删改元素。

====注意:二義性的tuple符号:

list在建立的時候使用[],tuple在建立的時候使用(),如果是建立一個空list則是a=[],如果是建立空tuple則是a=(),如果建立一個隻含有1個元素的tuple,不應該寫成a=(1)這會被python解釋成a=1,a是一個int類型的對象因為python遇到()的時候有二義性,到底是tuple還是普通的小括号,python規定當做小括号使用,是以聲明一個隻有1個元素的tuple應該是:a=(1,)注意不要缺少這個逗号。

====注意:“可變的”tuple

tuple的不可修改指的是每一個tuple中的元素所指向的對象都不發生位址變化,但是所指向的對象的内容卻可以改變,如:

a=('a','b',['A','B'])

a[2][0]='X'

a[2][1]='Y'

print(a)  -- > ('a','b',['X','Y'])

這種修改是合法的,因為對于tuple   a而言,a[2]這個元素位址并沒有發生改變,即并沒有指向其他的list,而這個未改變位址的list的内容發生改變并不影響tuple的規定。

7、條件判斷

if,elif,else判斷語句,用于分支判斷,if可以了解成判斷後面的語句是否為真,如果是真則執行if語句塊,如果不為真就一定為假,則執行else語句塊,使用elif可以增加多個判斷條件。連用多個if和elif的判斷邏輯類似于ACL通路控制清單,判斷順序也是自上而下,一條沒有滿足即順延到下一條判斷條件,一旦某一條判斷條件是真,則不再進行後續判斷,如果所有if和elif都判斷為假,則用最後的else作為permit any含義。

注意條件判斷後面不要遺漏:冒号,條件判斷還可以簡寫成if  x: 這個x隻要是非零整數、非空清單、非空tuple、非空字元串等等,都認為是True,否則認為是False。

input()函數用于擷取使用者輸入,無論使用者輸入的是數字、字元、還是字元串等等,都被input函數以str的類型傳回。

可以通過eval()函數擷取一個字元串的值,如:'2'就是2,'a'會得到變量a

8、循環

python中的循環有兩類

====for循環:

for循環用于周遊一個序列,将序列中的每一個元素指派給自定義的變量以便操作序列中的所有元素值,如:

注意:一般會使用list(range(10))來構造一個10個元素的清單,因為從0開始是以是0~9的10個元素。

for循環的循環執行依賴于明确的範圍周遊(無法依賴條件判斷)

====while循環:

while循環的執行依賴于while關鍵字後面的條件判斷,當為真的時候執行循環體,執行完畢後再次條件判斷,為假的時候跳出循環,是以循環體内部需要有一定的限制條件或者手段來保證有限次的循環後可以跳出,即while循環的執行依賴于條件判斷+循環體内部限制條件

注意:跳出while循環的時候,一定是第一次不滿足循環條件判斷的時候

====break:

在循環體内部使用break可以跳出目前一層循環,用于特殊、有需要的程式執行分支流程

====continue:

在循環體内部使用continue可以省略剩餘的循環體語句并立即開始下一次循環,如果是for就中斷并提前周遊下一個元素,如果是while就中斷并提前執行下一次條件判斷

注意:大量的、不加規劃的使用break和continue的确會導緻程式的邏輯、執行流程混亂,加重代碼的複雜度以及後期debug的工作量。

另外,就像無限疊代會導緻機器崩潰一樣,無限循環也會導緻機器崩潰,是以編寫循環首要注意的就是是否可以在必要的時候跳出循環體,尤其是while循環體中是否有足夠的限制條件和手段。

9、dict和set

就像list和tuple非常的類似,并且都是python的内置資料類型一樣。dict和set也是python的内置資料類型,也一樣非常類似。

====dict:

dict在python中稱為字典,是一種key-value對,其實類似于哈希表,即一個輸入(key),有着唯一的輸出(value),中間通過hash算法來完成唯一的映射。dict使用{}來表示,裡面填寫每一個key-value對使用逗号分隔。dict中的key就是哈希表中的輸入或者關鍵字,dict使用雜湊演算法将key映射成唯一的記憶體位址,該記憶體位址上可以儲存其他對象即value,是以key被要求不可變(即一旦初始化即不可再改變),如整數、字元串、元祖tuple等等,而value的值卻是可變的,但若value變化多次則會以最後一次的值為準。在dict中,key是沒有排序的,即無法使用dict[0]這種類似list和tuple的方式來擷取第1個元素,dict隻能使用d[key名稱]的形式來擷取這個key所對應的value。

dict使用d[key名稱]=value的方式來為一個dict新增鍵值對,也可以使用del  d[key]的方式删除一個鍵值對,或者是d.pop(key)的方式彈出一個鍵值對,dict使用d[key名稱]的方式來通路這個key對應的value,如果沒有該key則會報錯,是以通路方式還可以是:key  in  d 使用布爾判斷是否含有此key,或者是d.get(key,-1)擷取d的key的value,如果沒有key則傳回-1,預設傳回None無法在python解釋器中顯示結果。

遇到任何有聯系的兩個對象,都可以使其一成為key,另一個成為value放入dict中,在dict中的查找速度是非常快的基本等于O(1)。

====set:

set在python中稱為集合,更确切的說,就是一些不重複的對象的集合,之是以不說是序列,是因為set是無序的,即無法使用s[0]這種序列通路方式來通路,就像dict一樣,也是無序的。

同時,set的構造使用{}來表示,和dict一樣,但是set的對象并不是dict那樣的鍵值對,事實上,set的對象隻有key而沒有value。

可以使用s=set(某個序列)函數來構造一個集合,輸入需要是一個序列,可以是list、tuple、range(10)等。

set最重要的特性是:

1、set中對象無重複

2、set作為集合,可用于數學上的集合運算,如交集&,并集|

交集:取s1和s2中共有的部分作為結果,即交集是s1的子集,也是s2的子集

并集:将s1和s2所有元素整合并消除重複,即s1是并集的子集,s2頁是并集的子集

3、set可以增加或者減少對象,s.add(100), s.remove(2)如果新增多個重複的對象,set會自動過濾

====注意:

關于不可變對象:首先,對象不可變指的是某個對象一旦被構造并被初始化值之後,就不能再改變這個對象的位址以及這個對象的值,如:整數、字元串、tuple、dict的key等等。其次,不可變對象的一些函數如果涉及到需要改變對象的值,則一般會複制一份同值的對象并傳回,而原來的不可變對象還是沒有改變值,以此來保證對象的不可變性。對于可變對象,對象的函數如果涉及改變對象的值,則直接在原有對象上進行改變。如:

因為str1不可變,是以replace涉及修改值的時候傳回了另一個對象

因為list1可變,是以直接在list1對象上直接修改值,并不傳回另一個對象