- 參考書《Python基礎教程(第三版)》—— Magnus Lie Hetland
文章目錄
一、再看print和import
1. print()函數
- 原型
print( para,para,..,(sep = para),(end = para) ):none
- print()可以打印一個表達式,這個表達式要麼是字符串,要麼自動轉爲字符串形式打印
- print()中可以填任意多個參數,關鍵字實參
sep
和end
可以缺省sep
指定打印的兩個參數間的間隔符,缺省爲空格' '
end
指定打印的字符串的後綴,缺省爲換行符'\n'
#缺省sep和end
>>> print('A',1,2)
A 1 2
#設置sep爲'_'
>>> print('A',1,2,sep = '_')
A_1_2
#設置sep和end
>>> print('A',1,2,sep = '_',end = '*')
A_1_2*
#end尾綴可以是字符串
>>> print('A',1,2,sep = '_',end = 'AAAA')
A_1_2AAAA
2. import
-
從模塊導入
- 導入一個模塊:
import 模塊名
- 調用方法/函數:
模塊名.方法/函數名()
,這裏是方法/函數的引用 - 訪問屬性:
模塊名.屬性名
,這裏是原屬性的引用
- 調用方法/函數:
- 導入一個模塊中的所有屬性和方法/函數:
from 模塊名 import *
- 調用方法/函數:
方法/函數名()
,這裏是方法/函數的引用 - 訪問屬性:
屬性名
,這裏是原屬性的拷貝
- 調用方法/函數:
- 導入某個方法:
from 模塊名 import 方法名
- 導入某幾個方法:
from 模塊名 import 方法名1,方法名2,方法名3
- 導入一個模塊:
-
如果有兩個模塊包含一樣的方法名(如open)
- 給模塊起別名:
improt 模塊名 as 別名
- 給方法起別名:
from 模塊名 import 方法名 as 別名
- 給模塊起別名:
二、特殊賦值方法
1. 序列解包
- 序列解包:將一個序列或任何可迭代對象解包,並將得到的值存儲到一系列變量中
>>> values = 1,2,3
>>> values
(1, 2, 3)
#對元組進行解包
>>> x,y,z = values
>>> x,y,z
(1, 2, 3)
>>> x
1
>>> x,y
(1,2)
#利用序列解包交換變量值
>>> x,y = y,x
>>> x,y,z
(2, 1, 3)
- 序列解包在使用返回元組(或其他數列、可迭代對象啊)的函數/方法時很有用
>>> items = {'name': 'Tom', 'age': 18}
>>> key,value = items.popitem() #字典的popitem()方法,任意彈出字典中一個鍵值對
>>> key
'age'
>>> value
18
- 收集參數
- 使用序列解包時,要確保左邊給出的目標數目和被解包序列元素個數相同,否則出錯
- 用 “帶*變量” 收集多餘的序列元素,這樣帶*變量得到一個列表
- 這種方法可以用到函數參數列表中
>>> A,B = [1,2,3,4] #報錯
>>> A,B,*rest = [1,2,3,4]
>>> rest
>>> [3,4]
>>> A,B,*rest = [1,2,3]
>>> rest
>>> [3]
>>> A,*rest,B = [1,2,3,4,5]
>>> rest
>>> [2,3,4]
2. 鏈式賦值
x = y = somefunction()
#等價於
y = somefunction()
x = y
3. 增強賦值
- 可以使用
+=
和-=
,類似C++
>>> a = 10
>>> a += 2
>>> a
12
>>> str = 'ABC'
>>> str += 'D'
>>> str
'ABCD'
三、條件和條件語句 if-elif-else
1. 布爾值
- 標準真值是
True/False
,它們是1和0的別名
>>> True+1
2
>>> False == 0
True
-
用作布爾表達式時
- 以下被解釋爲False:
False
/None
/0
/''
/()
/[]
/{}
- 其他被解釋爲True
- 以下被解釋爲False:
-
bool和list一樣,可以用來轉換其他值構造bool類型
>>> bool("ABC")
>>> True
>>> bool('')
False
2. 條件語句
if-elif-else
結構
if expression1:
# code
elif expression2:
# code
...
elif expressionN:
# code
else:
# code
3. 布爾表達式
- 比較運算符
符號 | 說明 | |
---|---|---|
傳統比較運算符 | == / != / > / < / >= / <= |
類似C/C++中的比較符號 |
鏈式比較 | 1 <= number <= 10 |
等價於1 <= number && number <= 10 |
對象比較 | is / is not |
比較兩個對象是否爲同一個對象;而== 比較兩個對象是否相等 (不可將is用於比較數和字符串等不可改變的基本值,鑑於python在內部處理這些對象的方式,這樣做的結果是不可預測的) |
成員資格檢查 | in / not in |
如x in y 檢查x是否爲容器y的成員 |
# '=='檢查兩個對象是否相等
# 'is'檢查兩個對象是否相同(“指向同一個對象” / 或者時說“是同一個對象”)
>>> x = y = [1,2,3] # 等價於y = [1,2,3], x = y
>>> z = [1,2,3]
>>> x == y
True
>>> x == z
True
>>> x is y
True
>>> x is z
False
- 字符串和序列的比較
-
字符串是根據字符的字母排序進行比較的
-
本質上比較的是unicode編碼,字符是按碼點排列的
- 可以用ord(char)返回字符的Unicode值
- 可以用chr(int)將Unicode值轉爲字符返回
-
序列的比較方式也是這樣的
-
>>> ord('A')
65
>>> chr(65)
'A'
>>> [1,2]<[2,1]
True
>>> [2,[1,4]]<[2,[1,5]]
True
-
邏輯運算符
- 邏輯運算符用來連接多個布爾表達式,構成複合條件表達式
- python中的邏輯運算符:
and / or / not
- python的符合條件語句也有短路特性
運算符 操作 說明 and
與運算 類似C中 &&
or
或運算 類似C中 ||
not
非運算 類似C中 !
4. 斷言
- 斷言是if的“親戚”,僞代碼類似如下:
# 斷言的僞代碼
if not condition:
crash program
-
斷言的目的在於在程序出錯時立刻崩潰,而不是錯誤隱藏到之後再崩潰
-
基本上,可以用斷言要求某些條件得到滿足,比如判斷參數合法
-
斷言的形式
assert 條件表達式 (,'報錯字符串')
# 條件滿足,斷言報錯不被觸發
>>> age = 10
>>> assert 0 < age < 100
# 條件不滿足,觸發斷言報錯
>>> age = -1
>>> assert 0 < age < 100
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AssertionError
#可以在assert斷言後加一個說明字符串,這樣報錯的時候可以看到說明
>>> age = -1
>>> assert 0 < age < 100, "Age Error"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AssertionError: Age Error
四、循環語句
1. while循環
while 判斷條件:
循環體
2. for循環
- 基本上,可迭代對象是可以用for循環遍歷的對象。(後面再介紹迭代器,目前把可迭代對象視爲序列即可)
# 遍歷列表打印
words = ['apple','big','car']
for word in words:
print(word)
numbers = [1,2,3,4,5,6,7,8,9,10]
for num in numbers:
print(num)
- 爲了方便遍歷特定範圍的數據,python提供內置函數
range(begin,end)
>>> range(0,10)
range(0,10)
>>> list(range(0,10))
[0,1,2,3,4,5,6,7,8,9]
>>> list(range(5))
[0,1,2,3,4,5]
- 還可以加上步進長度參數
range(begin,end,step)
>>> list(range(10,0,-1))
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
>>> list(range(10,0,-2))
[10, 8, 6, 4, 2]
>>> list(range(10,0,-3))
[10, 7, 4, 1]
- 可以用類似序列的方法用for循環遍歷字典,但是字典內部是沒有順序的,所有這樣for循環打印的順序是不一定的,只能保證所有值都被處理。如果順序很重要,可以把鍵或值存入一個列表,對列表進行排序,再迭代
#打印所有鍵值對
d = {'x':1,'y':2 }
for key in d:
print(key,":",d[key])
#打印所有鍵值對(使用了序列解包)
d = {'x':1,'y':2 }
for key,value in d.items():
print(key,":",value)
3. 迭代工具
- python提供了一系列可以幫助迭代的函數,其中一些位於
itertools
模塊中,另外還有一些內置函數
(1)並行迭代 zip()
- 有時候可能想並行迭代兩個序列,可以用
zip(a,b,c...)
把任意多個序列"縫合"起來,並返回一個由元組組成的序列。可以把它轉換爲列表查看 - 當被縫合的序列長度不同時,zip將只縫合併返回最短序列長度個元素
>>> list1 = [1,2,3]
>>> list2 = ['A','B','C']
>>> list3 = [4,5,6,7,8,9]
>>> list(zip(list1,list2,list3))
[(1, 'A', 4), (2, 'B', 5), (3, 'C', 6)]
- zip配合序列解包,可以方便地進行多序列並行迭代
#不使用zip
names = ['Tom','Bill','Jack']
ages = [12,20,18]
for i in range(len(names)):
print(names[i],'is',ages[i],'years old')
#使用zip
names = ['Tom','Bill','Jack']
ages = [12,20,18]
for name,age in zip(names,ages):
print(name,'is',age,'years old')
(2)迭代時獲取索引
- 利用
enumerate(可迭代對象)
函數:返回一個由元組組成的序列,每個元組是由索引和元素值組成,用list()可以把這個序列轉爲元組列表。
>>> list(enumerate(['A','B','C','D']))
[(0, 'A'), (1, 'B'), (2, 'C'), (3, 'D')]
>>> list(enumerate('string'))
[(0, 's'), (1, 't'), (2, 'r'), (3, 'i'), (4, 'n'), (5, 'g')]
# 一個示例 ------------------------
lst = ['BBC','CCTV','ABC']
for index,item in enumerate(lst):
if 'B' in item:
lst[index] = 'X'
print(lst) # 打印['X', 'CCTV', 'X']
(3)反向迭代和排序後再迭代
- python提供了兩個內置函數
reversed(可迭代對象):list_reverseiterator object
和sorted(可迭代對象):list
,它們不修改原對象,而是返回反轉後的“列表反向迭代對象”和“排序後的列表”
lst = [4,3,5,7,6,5]
print(list(reversed(lst))) #打印[5, 6, 7, 5, 3, 4]
print(sorted(lst)) #打印[3, 4, 5, 5, 6, 7]
- 注意:
sorted()
返回一個列表,而reversed()
返回一個類似zip的更神祕的可迭代對象,我們不必關心這個到底意味着什麼,在for循環或join等方法中使用完全沒問題。但是不能對它進行索引或切片操作,也不能對它調用列表方法。要想當作列表一樣用的話,可以用list()對返回對象進行轉換
4. 跳出循環
- break(跳出循環)
#打印1~49
i = 1
while i<100:
if i == 50:#打印到50時跳出
break
print(i)
i += 1
- continue(跳過本次循環)
#打印1 2 4 5
i = 1
while i <= 5:
if i == 3: #i==3時跳過
i += 1
continue
print(i)
i += 1
五、簡單推導和字典推導
推到
不是語句,而是表達式- 列表推導是一種從其他列表創建列表的方法,類似集合推導,工作原理類似for循環
# 基本形式
>>> [x*x for x in range(10)]
[0,1,4,9,16,25,36,49,64,81,100]
# 增加一條if
>>>[x*x for x in range(10) if x % 3 == 0]
[0,9,36,81]
# 增加for
>>>[(x,y) for x in range(3) for y in range(4)]
[(0, 0), (0, 1), (0, 2), (0, 3), (1, 0), (1, 1), (1, 2), (1, 3), (2, 0), (2, 1), (2, 2), (2, 3)]
# 也可同時加入更多的if和for
>>>[x*x for x in range(10) if x % 3 == 0 and x*x<10]
[0,9]
>>>[x*x for x in range(10) if x % 3 == 0 if x*x<10]#可以連寫if代替複合條件
[0,9]
-
將上面的
[]
換成()
不能實現元組推導,這樣做將創建生成器 -
可以用
{}
進行字典推導
>>> squares = {i:"{} squared is {}".format(i,i**2) for i in range(10)}
>>> squares[8]
'8 squared is 64'
六、其他語句del/pass/exec/eval
1. pass語句
- pass語句不做任何事
- pass可以用作佔位符,因爲python中的代碼塊不能爲空,用pass填充代碼塊,可以讓程序運行並測試已經寫好的部分
flag = input()
if flag == '1':
print("...")
elif flag == '2': #分支沒有寫好,先跳過
pass
else:
print("xxx")
- 也可以插入一個字符串用作佔位符,這種做法尤其適合未完成的函數和類,因爲這種字符串將充當文檔字符串
def fibs(num):
'lalalala' # 文檔字符串(這個字符串會被作爲函數的一部分儲存起來)
result = [0,1]
for i in range(num-2):
result.append(result[-2]+result[-1])
return result
print(fibs.__doc__) # 打印lalalala
2. exec語句
- exec將字符串作爲代碼執行
>>> exec("print('Hello,world')")
Hello,world
- 大多數情況下,還應該向它傳遞一個命名空間——用於存放變量的地方,否則將污染命名空間(同名時覆蓋原本代碼中的變量或函數)
>>> from math import sqrt
>>> scope = {} # 定義一個字典作爲命名空間
>>> exec('sqrt = 1',scope) # exec的第二個參數指出命名空間,否則這裏的sqrt會污染從math導入的import
>>> sqrt(4) # 導入的sqrt正常運行
2.0
>>> scope['sqrt'] # 指定命名空間scope,通過exec執行賦值語句創建的變量位於scope中
1
- exec是一個過程,無返回值
- 注意
exec
可能引入不安全的代碼
3. eval語句
- eval計算用字符串表示的Python表達式值,並返回結果
# 創建一個python計算器
>>> eval(input("Enter an arithmetic expression:"))
- 類似exec,也可以像eval提供命名空間
4. del語句
- python中帶有垃圾回收機制,如果一個對象沒有任何人引用,將會被自動回收
>>> d = dict([('name','Tom') , ('age',18)])
>>> d = None #這時剛剛創建的字典將被釋放空間
del
語句也可以做到這一點,它不僅刪除變量到對象的引用關係,還刪除變量名稱。但是del語句不會刪除對象(事實上,python中無法手動釋放對象,python的垃圾回收機制會自動釋放不用的對象)
>>> x = [1,2,3]
>>> y = x
>>> del x
>>> y # 刪除x後,對象沒有消失,y仍然可引用;但若y也刪除,列表對象被自動回收
[1,2,3]