DayDayUP_Python自學記錄[1]_Python基礎知識

0 基礎知識

0.1 Python 標識符

在python裏,標識符有字母、數字、下劃線組成。
在python中,所有標識符可以包括英文、數字以及下劃線(_),但不能以數字開頭。
python中的標識符是區分大小寫的。
以下劃線開頭的標識符是有特殊意義的。以單下劃線開頭(_foo)的代表不能直接訪問的類屬性,需通過類提供的接口進行訪問,不能用”from xxx import *”而導入;
以雙下劃線開頭的(foo)代表類的私有成員;以雙下劃線開頭和結尾的(__foo)代表python裏特殊方法專用的標識,如init()代表類的構造函數。

0.2 Python保留字符

下面的列表顯示了在Python中的保留字。這些保留字不能用作常數或變數,或任何其他標識符名稱。
所有Python的關鍵字只包含小寫字母。

and exec    not
assert  finally or
break   for pass
class   from    print
continue    global  raise
def if  return
del import  try
elif    in  while
else    is  with
except  lambda  yield

0.3 多行語句

Python語句中一般以新行作爲爲語句的結束符。
但是我們可以使用斜槓( \)將一行的語句分爲多行顯示,如下所示:

total = item_one + \
        item_two + \
        item_three

語句中包含[], {} 或 () 括號就不需要使用多行連接符。如下實例:

days = ['Monday', 'Tuesday', 'Wednesday',
        'Thursday', 'Friday']

1 數據類型

計算機顧名思義就是可以做數學計算的機器,因此,計算機程序理所當然地可以處理各種數值。但是,計算機能處理的遠不止數值,還可以處理文本、圖形、音頻、視頻、網頁等各種各樣的數據,不同的數據,需要定義不同的數據類型。在Python中,能夠直接處理的數據類型有以下幾種:

1.1 整數

Python可以處理任意大小的整數,當然包括負整數,在Python程序中,整數的表示方法和數學上的寫法一模一樣,例如:1,100,-8080,0,等等。

計算機由於使用二進制,所以,有時候用十六進制表示整數比較方便,十六進制用0x前綴和0-9,a-f表示,例如:0xff00,0xa5b4c3d2,等等。

1.2 浮點數

浮點數也就是小數,之所以稱爲浮點數,是因爲按照科學記數法表示時,一個浮點數的小數點位置是可變的,比如,1.23x10^9和12.3x10^8是相等的。浮點數可以用數學寫法,如1.23,3.14,-9.01,等等。但是對於很大或很小的浮點數,就必須用科學計數法表示,把10用e替代,1.23x10^9就是1.23e9,或者12.3e8,0.000012可以寫成1.2e-5,等等。

整數和浮點數在計算機內部存儲的方式是不同的,整數運算永遠是精確的(除法難道也是精確的?是的!),而浮點數運算則可能會有四捨五入的誤差。

1.3 字符串

字符串是以”或”“括起來的任意文本,比如’abc’,”xyz”等等。請注意,”或”“本身只是一種表示方式,不是字符串的一部分,因此,字符串’abc’只有a,b,c這3個字符。

1.4 布爾值

布爾值和布爾代數的表示完全一致,一個布爾值只有True、False兩種值,要麼是True,要麼是False,在Python中,可以直接用True、False表示布爾值(請注意大小寫),也可以通過布爾運算計算出來。

布爾值可以用and、or和not運算。

and運算是與運算,只有所有都爲 True,and運算結果纔是 True。

or運算是或運算,只要其中有一個爲 True,or 運算結果就是 True。

not運算是非運算,它是一個單目運算符,把 True 變成 False,False 變成 True。

1.5 空值

空值是Python裏一個特殊的值,用None表示。None不能理解爲0,因爲0是有意義的,而None是一個特殊的空值。

此外,Python還提供了列表、字典等多種數據類型,還允許創建自定義數據類型,

1.6 整數和浮點數

Python支持對整數和浮點數直接進行四則混合運算,運算規則和數學上的四則運算規則完全一致。

基本的運算:

1 + 2 + 3   # ==> 6
4 * 5 - 6   # ==> 14
7.5 / 8 + 2.1   # ==> 3.0375

使用括號可以提升優先級,這和數學運算完全一致,注意只能使用小括號,但是括號可以嵌套很多層:

(1 + 2) * 3    # ==> 9
(2.2 + 3.3) / (1.5 * (9 - 0.3))    # ==> 0.42145593869731807

和數學運算不同的地方是,Python的整數運算結果仍然是整數,浮點數運算結果仍然是浮點數:

1 + 2    # ==> 整數 3
1.0 + 2.0    # ==> 浮點數 3.0

但是整數和浮點數混合運算的結果就變成浮點數了:

1 + 2.0    # ==> 浮點數 3.0

爲什麼要區分整數運算和浮點數運算呢?這是因爲整數運算的結果永遠是精確的,而浮點數運算的結果不一定精確,因爲計算機內存再大,也無法精確表示出無限循環小數,比如 0.1 換成二進制表示就是無限循環小數。

那整數的除法運算遇到除不盡的時候,結果難道不是浮點數嗎?我們來試一下:

11 / 4    # ==> 2

令很多初學者驚訝的是,Python的整數除法,即使除不盡,結果仍然是整數,餘數直接被扔掉。不過,Python提供了一個求餘的運算 % 可以計算餘數:

11 % 4    # ==> 3

如果我們要計算 11 / 4 的精確結果,按照“整數和浮點數混合運算的結果是浮點數”的法則,把兩個數中的一個變成浮點數再運算就沒問題了:

11.0 / 4    # ==> 2.75

1.7布爾類型

在Python中,布爾類型還可以與其他數據類型做 and、or和not運算,請看下面的代碼:

a = True
print a and 'a=T' or 'a=F'

計算結果不是布爾類型,而是字符串 ‘a=T’,這是爲什麼呢?

因爲Python把0、空字符串”和None看成 False,其他數值和非空字符串都看成 True,所以:

True and ‘a=T’ 計算結果是 ‘a=T’
繼續計算 ‘a=T’ or ‘a=F’ 計算結果還是 ‘a=T’
要解釋上述結果,又涉及到 and 和 or 運算的一條重要法則:短路計算。

  1. 在計算 a and b 時,如果 a 是 False,則根據與運算法則,整個結果必定爲 False,因此返回 a;如果 a 是 True,則整個計算結果必定取決與 b,因此返回 b。

  2. 在計算 a or b 時,如果 a 是 True,則根據或運算法則,整個計算結果必定爲 True,因此返回 a;如果 a 是 False,則整個計算結果必定取決於 b,因此返回 b。

所以Python解釋器在做布爾運算時,只要能提前確定計算結果,它就不會往後算了,直接返回結果。

2 print語句

print語句可以向屏幕上輸出指定的文字。比如輸出’hello, world’,用代碼實現如下:

>>> print 'hello, world'

注意:

1.當我們在Python交互式環境下編寫代碼時,>>>是Python解釋器的提示符,不是代碼的一部分。

2.當我們在文本編輯器中編寫代碼時,千萬不要自己添加 >>>。

print語句也可以跟上多個字符串,用逗號“,”隔開,就可以連成一串輸出:

>>> print 'The quick brown fox', 'jumps over', 'the lazy dog'
The quick brown fox jumps over the lazy dog

print會依次打印每個字符串,遇到逗號“,”會輸出一個空格,因此,輸出的字符串是這樣拼起來的:

print也可以打印整數,或者計算結果:

>>> print 300
300    #運行結果
>>> print 100 + 200
300    #運行結果

因此,我們可以把計算100 + 200的結果打印得更漂亮一點:

>>> print '100 + 200 =', 100 + 200
100 + 200 = 300     #運行結果

注意: 對於100 + 200,Python解釋器自動計算出結果300,但是,’100 + 200 =’是字符串而非數學公式,Python把它視爲字符串,請自行解釋上述打印結果。

print()格式化輸出

  • 格式
    print(format(value,format_modifier))
    print(format(value,’m,nf’))
  • 說明
    value:數值
    format_modifier:格式字
    m:輸出佔位符
    n:精度
    eg:
>>> print (format(12.3456,'6.2f'))  
 12.35  
>>> print (format(12.3456,'6.9f'))  
12.345600000   
>>> print (format(0.3456,'.2%'))  
34.56%  
>>> print (format(0.3456,'3.2%'))  
34.56%  
>>> print (format(0.3456,'1.3%'))  
34.560%  

3 註釋

任何時候,我們都可以給程序加上註釋。註釋是用來說明代碼的,給自己或別人看,而程序運行的時候,Python解釋器會直接忽略掉註釋,所以,有沒有註釋不影響程序的執行結果,但是影響到別人能不能看懂你的代碼。

Python的註釋以 # 開頭,後面的文字直到行尾都算註釋

在Python中,變量的概念基本上和初中代數的方程變量是一致的。

4 變量

例如,對於方程式 y=x*x ,x就是變量。當x=2時,計算結果是4,當x=5時,計算結果是25。

只是在計算機程序中,變量不僅可以是數字,還可以是任意數據類型。

在Python程序中,變量是用一個變量名錶示,變量名必須是大小寫英文、數字和下劃線(_)的組合,且不能用數字開頭,比如:

a = 1
變量a是一個整數。

t_007 = 'T007'
變量t_007是一個字符串。

在Python中,等號=是賦值語句,可以把任意數據類型賦值給變量,同一個變量可以反覆賦值,而且可以是不同類型的變量,例如:

a = 123    # a是整數
print a
a = 'imooc'   # a變爲字符串
print a

這種變量本身類型不固定的語言稱之爲動態語言,與之對應的是靜態語言。

靜態語言在定義變量時必須指定變量類型,如果賦值的時候類型不匹配,就會報錯。例如Java是靜態語言,賦值語句如下(// 表示註釋):

int a = 123; // a是整數類型變量
a = “mooc”; // 錯誤:不能把字符串賦給整型變量
和靜態語言相比,動態語言更靈活,就是這個原因。

請不要把賦值語句的等號等同於數學的等號。比如下面的代碼:

x = 10
x = x + 2

如果從數學上理解x = x + 2那無論如何是不成立的,在程序中,賦值語句先計算右側的表達式x + 2,得到結果12,再賦給變量x。由於x之前的值是10,重新賦值後,x的值變成12。

最後,理解變量在計算機內存中的表示也非常重要。當我們寫:a = ‘ABC’時,Python解釋器幹了兩件事情:

  1. 在內存中創建了一個’ABC’的字符串;

  2. 在內存中創建了一個名爲a的變量,並把它指向’ABC’。

也可以把一個變量a賦值給另一個變量b,這個操作實際上是把變量b指向變量a所指向的數據,例如下面的代碼:

a = 'ABC'
b = a
a = 'XYZ'
print b

最後一行打印出變量b的內容到底是’ABC’呢還是’XYZ’?如果從數學意義上理解,就會錯誤地得出b和a相同,也應該是’XYZ’,但實際上b的值是’ABC’,讓我們一行一行地執行代碼,就可以看到到底發生了什麼事:

執行a = ‘ABC’,解釋器創建了字符串 ‘ABC’和變量 a,並把a指向 ‘ABC’:
執行b = a,解釋器創建了變量 b,並把b指向 a 指向的字符串’ABC’:
執行a = ‘XYZ’,解釋器創建了字符串’XYZ’,並把a的指向改爲’XYZ’,但b並沒有更
所以,最後打印變量b的結果自然是’ABC’了。

6 raw字符串與多行字符串

如果一個字符串包含很多需要轉義的字符,對每一個字符都進行轉義會很麻煩。爲了避免這種情況,我們可以在字符串前面加個前綴 r ,表示這是一個 raw 字符串,裏面的字符就不需要轉義了。例如:

r'\(~_~)/ \(~_~)/'

但是r’…’表示法不能表示多行字符串,也不能表示包含’和 “的字符串(爲什麼?)

如果要表示多行字符串,可以用”’…”’表示:

'''Line 1
Line 2
Line 3'''

上面這個字符串的表示方法和下面的是完全一樣的:

'Line 1\nLine 2\nLine 3'

還可以在多行字符串前面添加 r ,把這個多行字符串也變成一個raw字符串:

r'''Python is created by "Guido".
It is free and easy to learn
Let's start learn Python in imooc!'''

7 Unicode字符串

字符串還有一個編碼問題。

因爲計算機只能處理數字,如果要處理文本,就必須先把文本轉換爲數字才能處理。最早的計算機在設計時採用8個比特(bit)作爲一個字節(byte),所以,一個字節能表示的最大的整數就是255(二進制11111111=十進制255),0 - 255被用來表示大小寫英文字母、數字和一些符號,這個編碼表被稱爲ASCII編碼,比如大寫字母 A 的編碼是65,小寫字母 z 的編碼是122。

如果要表示中文,顯然一個字節是不夠的,至少需要兩個字節,而且還不能和ASCII編碼衝突,所以,中國製定了GB2312編碼,用來把中文編進去。

類似的,日文和韓文等其他語言也有這個問題。爲了統一所有文字的編碼,Unicode應運而生。Unicode把所有語言都統一到一套編碼裏,這樣就不會再有亂碼問題了。

Unicode通常用兩個字節表示一個字符,原有的英文編碼從單字節變成雙字節,只需要把高字節全部填爲0就可以。

因爲Python的誕生比Unicode標準發佈的時間還要早,所以最早的Python只支持ASCII編碼,普通的字符串’ABC’在Python內部都是ASCII編碼的。

Python在後來添加了對Unicode的支持,以Unicode表示的字符串用u’…’表示,比如:

print u'中文'

中文
注意: 不加 u ,中文就不能正常顯示。

Unicode字符串除了多了一個 u 之外,與普通字符串沒啥區別,轉義字符和多行表示法仍然有效:

轉義:

u'中文\n日文\n韓文'
多行:

u'''第一行
第二行'''
raw+多行:

ur'''Python的Unicode字符串支持"中文",
"日文",
"韓文"等多種語言'''

如果中文字符串在Python環境下遇到 UnicodeDecodeError,這是因爲.py文件保存的格式有問題。可以在第一行添加註釋

# -*- coding: utf-8 -*-

目的是告訴Python解釋器,用UTF-8編碼讀取源代碼。然後用Notepad++ 另存爲… 並選擇UTF-8格式保存。

8 list 和Tuple 類型

8.1 創建list

Python內置的一種數據類型是列表:list。list是一種有序的集合,可以隨時添加和刪除其中的元素。

比如,列出班裏所有同學的名字,就可以用一個list表示:

>>> ['Michael', 'Bob', 'Tracy']
['Michael', 'Bob', 'Tracy']

list是數學意義上的有序集合,也就是說,list中的元素是按照順序排列的。

構造list非常簡單,按照上面的代碼,直接用 [ ] 把list的所有元素都括起來,就是一個list對象。通常,我們會把list賦值給一個變量,這樣,就可以通過變量來引用list:

>>> classmates = ['Michael', 'Bob', 'Tracy']
>>> classmates # 打印classmates變量的內容
['Michael', 'Bob', 'Tracy']

由於Python是動態語言,所以list中包含的元素並不要求都必須是同一種數據類型,我們完全可以在list中包含各種數據:

>>> L = ['Michael', 100, True]

一個元素也沒有的list,就是空list

>>> empty_list = []

8.2 按照索引訪問list

由於list是一個有序集合,所以,我們可以用一個list按分數從高到低表示出班裏的3個同學:

>>> L = ['Adam', 'Lisa', 'Bart']

那我們如何從list中獲取指定第 N 名的同學呢?方法是通過索引來獲取list中的指定元素。

需要特別注意的是,索引從 0 開始,也就是說,第一個元素的索引是0,第二個元素的索引是1,以此類推。

因此,要打印第一名同學的名字,用 L[0]:

>>> print L[0]
Adam

要打印第二名同學的名字,用 L[1]:

>>> print L[1]
Lisa

要打印第三名同學的名字,用 L[2]:

>>> print L[2]
Bart

要打印第四名同學的名字,用 L[3]:

>>> print L[3]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range

報錯了!IndexError意思就是索引超出了範圍,因爲上面的list只有3個元素,有效的索引是 0,1,2。

所以,使用索引時,千萬注意不要越界。

8.3 倒序訪問list

我們還是用一個list按分數從高到低表示出班裏的3個同學:

>>> L = ['Adam', 'Lisa', 'Bart']

這時,老師說,請分數最低的同學站出來。

要寫代碼完成這個任務,我們可以先數一數這個 list,發現它包含3個元素,因此,最後一個元素的索引是2:

>>> print L[2]
Bart

有沒有更簡單的方法?

有!

Bart同學是最後一名,俗稱倒數第一,所以,我們可以用 -1 這個索引來表示最後一個元素:

>>> print L[-1]
Bart

Bart同學表示躺槍。

類似的,倒數第二用 -2 表示,倒數第三用 -3 表示,倒數第四用 -4 表示:

>>> print L[-2]
Lisa
>>> print L[-3]
Adam
>>> print L[-4]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range

L[-4] 報錯了,因爲倒數第四不存在,一共只有3個元素。

使用倒序索引時,也要注意不要越界。

8.4 添加新元素

現在,班裏有3名同學:

>>> L = ['Adam', 'Lisa', 'Bart']

今天,班裏轉來一名新同學 Paul,如何把新同學添加到現有的 list 中呢?

第一個辦法是用 list 的 append() 方法,把新同學追加到 list 的末尾:

>>> L = ['Adam', 'Lisa', 'Bart']
>>> L.append('Paul')
>>> print L
['Adam', 'Lisa', 'Bart', 'Paul']

append()總是把新的元素添加到 list 的尾部。

如果 Paul 同學表示自己總是考滿分,要求添加到第一的位置,怎麼辦?

方法是用list的 insert()方法,它接受兩個參數,第一個參數是索引號,第二個參數是待添加的新元素:

>>> L = ['Adam', 'Lisa', 'Bart']
>>> L.insert(0, 'Paul')
>>> print L
['Paul', 'Adam', 'Lisa', 'Bart']

L.insert(0, ‘Paul’) 的意思是,’Paul’將被添加到索引爲 0 的位置上(也就是第一個),而原來索引爲 0 的Adam同學,以及後面的所有同學,都自動向後移動一位。

8.5 從list刪除元素

Paul同學剛來幾天又要轉走了,那麼我們怎麼把Paul 從現有的list中刪除呢?

如果Paul同學排在最後一個,我們可以用list的pop()方法刪除:

>>> L = ['Adam', 'Lisa', 'Bart', 'Paul']
>>> L.pop()
'Paul'
>>> print L
['Adam', 'Lisa', 'Bart']

pop()方法總是刪掉list的最後一個元素,並且它還返回這個元素,所以我們執行 L.pop() 後,會打印出 ‘Paul’。

如果Paul同學不是排在最後一個怎麼辦?比如Paul同學排在第三:

>>> L = ['Adam', 'Lisa', 'Paul', 'Bart']

要把Paul踢出list,我們就必須先定位Paul的位置。由於Paul的索引是2,因此,用 pop(2)把Paul刪掉:

>>> L.pop(2)
'Paul'
>>> print L
['Adam', 'Lisa', 'Bart']

8.6 替換元素

假設現在班裏仍然是3名同學:

>>> L = ['Adam', 'Lisa', 'Bart']

現在,Bart同學要轉學走了,碰巧來了一個Paul同學,要更新班級成員名單,我們可以先把Bart刪掉,再把Paul添加進來。

另一個辦法是直接用Paul把Bart給替換掉:

>>> L[2] = 'Paul'
>>> print L
L = ['Adam', 'Lisa', 'Paul']

對list中的某一個索引賦值,就可以直接用新的元素替換掉原來的元素,list包含的元素個數保持不變。

由於Bart還可以用 -1 做索引,因此,下面的代碼也可以完成同樣的替換工作:

>>> L[-1] = 'Paul'

8.7 創建tuple

tuple是另一種有序的列表,中文翻譯爲“ 元組 ”。tuple 和 list 非常類似,但是,tuple一旦創建完畢,就不能修改了。

同樣是表示班裏同學的名稱,用tuple表示如下:

>>> t = ('Adam', 'Lisa', 'Bart')

創建tuple和創建list唯一不同之處是用( )替代了[ ]。

現在,這個 t 就不能改變了,tuple沒有 append()方法,也沒有insert()和pop()方法。所以,新同學沒法直接往 tuple 中添加,老同學想退出 tuple 也不行。

獲取 tuple 元素的方式和 list 是一模一樣的,我們可以正常使用 t[0],t[-1]等索引方式訪問元素,但是不能賦值成別的元素,不信可以試試:

>>> t[0] = 'Paul'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment

8.8創建單元素tuple

tuple和list一樣,可以包含 0 個、1個和任意多個元素。

包含多個元素的 tuple,前面我們已經創建過了。

包含 0 個元素的 tuple,也就是空tuple,直接用 ()表示:

>>> t = ()
>>> print t
()

創建包含1個元素的 tuple 呢?來試試:

>>> t = (1)
>>> print t
1

好像哪裏不對!t 不是 tuple ,而是整數1。爲什麼呢?

因爲()既可以表示tuple,又可以作爲括號表示運算時的優先級,結果 (1) 被Python解釋器計算出結果 1,導致我們得到的不是tuple,而是整數 1。

正是因爲用()定義單元素的tuple有歧義,所以 Python 規定,單元素 tuple 要多加一個逗號“,”,這樣就避免了歧義:

>>> t = (1,)
>>> print t
(1,)

Python在打印單元素tuple時,也自動添加了一個“,”,爲了更明確地告訴你這是一個tuple。

多元素 tuple 加不加這個額外的“,”效果是一樣的:

8.9 “可變”的tuple

前面我們看到了tuple一旦創建就不能修改。現在,我們來看一個“可變”的tuple:

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

注意到 t 有 3 個元素:’a’,’b’和一個list:[‘A’, ‘B’]。list作爲一個整體是tuple的第3個元素。list對象可以通過 t[2] 拿到:

>>> L = t[2]

然後,我們把list的兩個元素改一改:

>>> L[0] = 'X'
>>> L[1] = 'Y'

再看看tuple的內容:

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

不是說tuple一旦定義後就不可變了嗎?怎麼現在又變了?

別急,我們先看看定義的時候tuple包含的3個元素:
當我們把list的元素’A’和’B’修改爲’X’和’Y’後,tuple變爲:
表面上看,tuple的元素確實變了,但其實變的不是 tuple 的元素,而是list的元素。

tuple一開始指向的list並沒有改成別的list,所以,tuple所謂的“不變”是說,tuple的每個元素,指向永遠不變。即指向’a’,就不能改成指向’b’,指向一個list,就不能改成指向其他對象,但指向的這個list本身是可變的!

理解了“指向不變”後,要創建一個內容也不變的tuple怎麼做?那就必須保證tuple的每一個元素本身也不能變。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章