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