Python 條件判斷與三元表達式
判斷:if, if else ,if elif
#### 判斷:if, if else ,if elif
#單if
age=88
if age<18:
print('teenage')
#if else
if age<18:
print('teenage')
else:
print('adult')
#if elif
if age<18:
print('teenage')
elif age >18 and age <60:
print('adult')
elif age>60:
print('elder')
輸出結果爲:
adult
elder
%whos
輸出結果爲:
Variable Type Data/Info
----------------------------
age int 88
三元表達式
#三元表達式
age=18
'a' if age>50 else 'b'
輸出結果爲:
'b'
擴展閱讀:Python三元表達的左右表達式問題
a=b=c=15
a=5 if b>12 else 3#合法
a=3 if b>15 else 33
#感受一下,先判斷,如果是,就對某變量操作,不是,還是對某變量操作和。。
#這也是爲什麼,expression只能放在左邊,因爲三元只能對一個變量操作。。
循環與循環控制
For循環與While循環
list(range(7))
輸出結果爲:
[0, 1, 2, 3, 4, 5, 6]
item=5
while True:
item=item+1
if item>100:
break
str1='weijichen.cn'
for item in str1:
print(item)
for item in range(7):
if item==5:
continue
print (item)
countnum=1
while True:
print(item)
countnum+=1
break與continue循環控制
#break 打破循環
#continue 跳過本次循環
i=0
while True:
i+=1
if i==3:
continue
if i>5:
break
print(i)
列表/字典 推導式 List/Dict Comprehension,可迭代對象Iterable,迭代器iterator,生成器generator
l1=[1,2,3,4,5]
l2={item for item in range(1,7)}
l3=(item for item in range(1,7))
l1,l2,list(l3)
輸出結果爲:
([1, 2, 3, 4, 5], {1, 2, 3, 4, 5, 6}, [1, 2, 3, 4, 5, 6])
def g2_func(n):
for i in range(n):
yield i**2
g2=g2_func(50)
list(g2)
什麼是yield?可以參考:Python中yield的用法詳解
for item in l2:
print(item)
#列表推導式:從一個列表中生成一個新的列表,簡化了循環的寫法
l1= {x for x in range(30) if x%3==0}
輸出結果爲:
1
2
3
4
5
6
#字典推導式:從能生成k,v的循環中生成一個新的字典,簡化了循環的寫法
str1='i love china for ever!'
{item:itemno for itemno,item in enumerate(str1)}
輸出結果爲:
{'i': 9,
' ': 16,
'l': 2,
'o': 14,
'v': 18,
'e': 19,
'c': 7,
'h': 8,
'n': 10,
'a': 11,
'f': 13,
'r': 20,
'!': 21}
#列表推導式:從一個列表中生成一個新的列表,簡化了循環的寫法
l1= {x for x in range(30) if x%3==0}
print(l1)
#可迭代對象Iterable:可以被for循環的對象統稱爲可迭代對象Iterable,list,str,dict這些都是可迭代類型
#迭代器Iterator:可以被next調用的迭代器。
#next(l1) #TypeError: 'list' object is not an iterator
#使用iter將一來個可迭代對象變爲迭代器
l1=iter(l1)
next(l1),next(l1)
輸出結果爲:
{0, 3, 6, 9, 12, 15, 18, 21, 24, 27}
(0, 3)
#生成器Generator:首先是一個迭代器,然後其內容是按需生成
#列表是一次性生成,缺點是當內容過大時會佔用大量內容,那能不能用到多少生成多少呢?
#Python裏一邊循環一邊計算(惰性計算)的迭代器稱爲生成器(Generator)
#1.直接從列表表達式生成
g1= (x**2 for x in range(30) if x%2==0)
type(g1)
next(g1),next(g1),next(g1),next(g1),g1.__next__(),g1.__next__()
輸出結果爲:
(0, 4, 16, 36, 64, 100)
#2.函數生成,與yield關鍵字
def g2_func(n):
for i in range(n):
yield i**2
g2=g2_func(7)
next(g2),next(g2),g2.__next__(),g2.__next__(),g2.__next__(),g2.__next__()
輸出結果爲:
(0, 1, 4, 9, 16, 25)
#yield from/子迭代器,後面直接是可迭代對象。
def yield_from_iter(iter_object):
yield from iter_object
y1=yield_from_iter('China')
y1.__next__(),next(y1)
輸出結果爲:
('C', 'h')
異常與調試
#一個出現異常的例子
print(77/0)
print(77/6)
輸出結果爲:
---------------------------------------------------------------------------
ZeroDivisionError Traceback (most recent call last)
<ipython-input-2-ab0faba5f642> in <module>
1 #一個出現異常的例子
----> 2 print(77/0)
3 print(77/6)
ZeroDivisionError: division by zero
%debug
輸出結果爲:
> [0;32m<ipython-input-2-ab0faba5f642>[0m(2)[0;36m<module>[0;34m()[0m
[0;32m 1 [0;31m[0;31m#一個出現異常的例子[0m[0;34m[0m[0;34m[0m[0;34m[0m[0m
[0m[0;32m----> 2 [0;31m[0mprint[0m[0;34m([0m[0;36m77[0m[0;34m/[0m[0;36m0[0m[0;34m)[0m[0;34m[0m[0;34m[0m[0m
[0m[0;32m 3 [0;31m[0mprint[0m[0;34m([0m[0;36m77[0m[0;34m/[0m[0;36m6[0m[0;34m)[0m[0;34m[0m[0;34m[0m[0m
[0m
ipdb> quit
異常/exception對象
異常同樣也是Python對象,表示一個在程序執行過程中發生了影響正常運行時而產生的一個事件(產生一個traceback.)
常見異常 | 說明 |
---|---|
NameError | 嘗試訪問一個沒有申明的變量 |
ZeroDivisionError | 除數爲0 |
SyntaxError | 語法錯誤 |
IndexError | 索引超出序列範圍 |
KeyError | 請求一個不存在的字典關鍵字 |
IOError | 輸入輸出錯誤(比如你要讀的文件不存在) |
AttributeError | 嘗試訪問未知的對象屬性 |
ValueError | 傳給函數的參數類型不正確,比如給int()函數傳入字符串形 |
開啓調試
#沒發生異常,沒有traceback就沒辦法debug.
#在錯誤異常發生時,我們可以運用%debug來開啓調試
%debug
輸出結果爲:
> [1;32m<ipython-input-36-0dd6b2efe6f0>[0m(1)[0;36m<module>[1;34m()[0m
[1;32m----> 1 [1;33m[0ma[0m[1;33m=[0m[0mnever_named_value[0m[1;33m[0m[0m
[0m[1;32m 2 [1;33m[0mprint[0m[1;33m([0m[1;34m'end line'[0m[1;33m)[0m[1;33m[0m[0m
[0m
ipdb> exit
#### 開啓自動調試
%pdb on
#異常發生時,調用堆棧幀被traceback保存,所以可以進行debug.
輸出結果爲:
Automatic pdb calling has been turned ON
aslkdfjoiuwejlas
輸出結果爲:
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-44-5c4051d97978> in <module>()
----> 1 aslkdfjoiuwejlas
NameError: name 'aslkdfjoiuwejlas' is not defined
> [1;32m<ipython-input-44-5c4051d97978>[0m(1)[0;36m<module>[1;34m()[0m
[1;32m----> 1 [1;33m[0maslkdfjoiuwejlas[0m[1;33m[0m[0m
[0m
ipdb> help
Documented commands (type help <topic>):
========================================
EOF cl disable interact next psource rv unt
a clear display j p q s until
alias commands down jump pdef quit source up
args condition enable l pdoc r step w
b cont exit list pfile restart tbreak whatis
break continue h ll pinfo return u where
bt d help longlist pinfo2 retval unalias
c debug ignore n pp run undisplay
Miscellaneous help topics:
==========================
exec pdb
ipdb> quit
# a=1
# print(never_named_value)
# b=2
# print(never_named_value1)
def test(a,b,c=10):
print(d)
return a+b+c
test(5,4)
ff=33331
adea=333
調試相關命令
pdb 常用命令 | 解釋 |
---|---|
break 或 b | 設置斷點 設置斷點 |
continue 或 c | 繼續執行程序 |
list 或 l | 查看當前行的代碼段 |
step 或 s | 進入函數 |
return 或 r | 執行代碼直到從當前函數返回 |
pp | 打印變量的值 |
help | 幫助 |
Documented commands (type help <topic>):
========================================
EOF cl disable interact next psource rv unt
a clear display j p q s until
alias commands down jump pdef quit source up
args condition enable l pdoc r step w
b cont exit list pfile restart tbreak whatis
break continue h ll pinfo return u where
bt d help longlist pinfo2 retval unalias
c debug ignore n pp run undisplay
Miscellaneous help topics:
==========================
exec pdb
主動設置斷點進行調試
#b列出所有已有斷點, ignore,disable,enable,也可以指定文件名設置斷點,也可以設置條件。
import pdb
i= 0
while i<10:
print(i)
pdb.set_trace()
i += 1
pdb.set_trace()
num=1
觸發斷點後的執行
c,continue,執行到下一個斷點
n,next,單步執行 n
n(ext)
Continue execution until the next line in the current function
is reached or it returns.
s,step,進入可調對象
棧幀選擇
w,輸出整個調用棧,u,d上下選擇前後棧幀
棧幀打印:
where,w
退出
q,quit,exit
捕獲並處理異常對象
捕捉異常對象要使用try/except,或try/else,try/finally 語句
try語句用來檢測try語句塊中的錯誤,從而讓except語句捕獲異常信息並處理
例如NameError:在名字空間訪問時出錯時會導致,也是咱們上邊課程一直講到的
a=never_named_value
print('end line')
輸出結果爲:
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-38-0dd6b2efe6f0> in <module>()
----> 1 a=never_named_value
2 print('end line')
NameError: name 'never_named_value' is not defined
#try except else
try:
a=never_named_value
print(int(a))
except ValueError:#發生ValueError錯誤執行以下代碼
print ("Error: 函數參數傳值錯誤")
except NameError:#發生NameError錯誤執行以下代碼
print ("Error: 名稱空間使用出錯")
else:
print('Everything is fine')
print('end line')
#try-finally 無法是否捕獲了異常,都會執行finally後的語句
延伸閱讀:追蹤(traceback)
當簡單的異常處理給我們的信息已經無法解決調試問題時,可以使用traceback對象進行深入觀察。
追蹤是在出現異常時用於回溯的對象,與棧幀相反。由於異常時纔會構建,而異常未捕獲時會一直向外層棧幀拋出,所以需要使用try才能見到這個對象。
你可以使用sys模塊的exc_info()函數獲得它,這個函數返回一個元組,元素分別是異常類型、異常對象、追蹤。
對象中包含出錯的行數、位置等數據。
traceback的屬性全部是隻讀,例如如下屬性:
- tb_next: 追蹤的下一個追蹤對象
- tb_frame: 當前追蹤對應的棧幀
- tb_lineno: 當前追蹤的行號
import sys, traceback
try:
a=never_named_value
print(int(a))
except ValueError:#發生ValueError錯誤執行以下代碼
print ("Error: 函數參數傳值錯誤")
except NameError:#發生NameError錯誤執行以下代碼
print ("Error: 名稱空間使用出錯")
#使用sys.exc_info獲得tb對象
exc_type, exc_value, exc_traceback_obj=sys.exc_info()
print('元組內三個對象',exc_type, exc_value, exc_traceback_obj)
#直接打印tb對象內的主要信息
traceback.print_exc()
#traceback對象內更多內容
print('tb對象內更多信息',exc_traceback_obj.tb_frame,exc_traceback_obj.tb_lasti)
else:
print('Everything is fine')
手動拋出異常
除了由程序觸發異常,也可以使用raise
手動拋出一個通用的異常類型
raise ValueError('類別錯誤')
def addfunc(a,b):
if type(a)!=type(b):
raise ValueError('類別錯誤') #或者 raise ValueError,'Invalid value'
return a+b
addfunc(5,'f')
if len(list(range(12))) <= 10:
raise AssertionError('list has too less items')
練習題:
詞頻統計
請統計以下列表中,每個單詞出現的次數,以字典的形式給出
l1=[‘sklearn’,‘AI’,‘weijichen.com’,‘Caffe’,‘AI’,‘sklearn’,‘AI’,‘Julyedu’,‘Tensorflow’,‘sklearn’,‘Keras’,‘CNN’,‘DropOut’,‘MXNET’,‘amazon aws servier’]
l1=['sklearn','AI','weijichen.com','Caffe','AI','sklearn','AI','Julyedu','Tensorflow','sklearn','Keras','CNN','DropOut','MXNET','amazon aws servier']
print(l1)
a=dict.fromkeys(l1,0)
print(a)
for item in l1:
a[item]+=1
print(a)
在不改變順序的前提下,去除一個列表中相領且重複的元素。
l1=[1,2,3,4,4,4,4,4,4,5,6,6,8,8,13,12,12,12,12]
l1=[1,2,3,4,4,4,4,4,4,5,6,6,8,8,13,12,12,12,12]
lastnumber=-1
l2=[]
for item in l1:
if lastnumber ==item:
continue
else:
lastnumber=item
l2.append(item)
l2
請分別使用循環和列表推導式找出l1這個列表中單詞長度大於7的單詞
l1=['AI','weijichen.com','Caffe','AI','sklearn','Julyedu','Tensorflow','sklearn','Keras','CNN','DropOut','MXNET','amazon aws servier']
l1=['AI','weijichen.com','Caffe','AI','sklearn','Julyedu','Tensorflow','sklearn','Keras','CNN','DropOut','MXNET','amazon aws servier']
#循環
for item in l1:
if len(item) > 7:
print(item)
#列表推導式
print([item for item in l1 if len(item) > 7])
使用列表推導式,打印出colors與sizes這兩個列表的所有(組合)
colors=['black','white']
sizes=['S','M','L']
colors=['black','white']
sizes=['S','M','L']
print({(key,value) for key in sizes for value in colors })
請創建一段代碼,能生成Fibonacci數列中的前50個
- 斐波那契數列(Fibonacci sequence),又稱黃金分割數列、因數學家列昂納多·斐波那契(Leonardoda Fibonacci)以兔子繁殖爲例子而引入,故又稱爲“兔子數列”
- 指的是這樣一個數列:1、1、2、3、5、8、13、21、34…,即每個數字都是前兩個數字的和
def fibonacci(n):
a,b=0,1
for i in range(n+1):
a,b=b,a+b
return a
for i in range(20):
print(fibonacci(i),end=' ')
輸出結果爲:
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765