第二部分 条件、循环及其他语句
2.1 print、import 和 input
2.1.1 打印多个参数
👇print 逗号分隔参数打印结果会在各参数间用空格分隔。
>>> print('Hello',',','World!')
Hello , World!
可使用加法解决。
>>> print('Hello' + ',' + 'World!')
Hello,World!
也可自定义分隔符以及结束字符串:
>>> print('What', 'a', 'nice', 'day!', sep='_', end='~~~')
What_a_nice_day!~~~
- 利用 % 格式化输出
>>> print('123%d567'%4) 1234567 >>> print('12%d45%d789'%(3,6)) 123456789 >>> print('12%d45%d789%10s'%(3,6,'end')) 123456789 end
利用input()以及评估函数eval()
>>> t = input("请输入:")
请输入:1
>>> t
'1'
>>> eval(t)
1
>>> eval('print("Hello World")')
Hello World
>>> eval("print("Hello World")")
SyntaxError: invalid syntax
*最后一例中里外引号不能相同,否则会报错。
2.1.2 模块导入
- 常用导入方法
import module
from module import function
from module import func1, func2, func3
from module import* - 模块函数重名解决办法
方法一:直接使用
module1.xxx(…)
module2.xxx(…)
方法二:指定别名
import xxx as …
例如:
from module1 import open as open1
from module2 import open as open2
2.2 赋值语句
2.2.1 序列解包
★★★★★★
def:将一个序列(或任何可迭代的对象)解包,并将得到的值存储到一系列变量中。
-
同时(并行)给多个变量赋值
>>> x, y, z = 1, 2, 3 >>> print(x, y, z) 1 2 3 >>> x, y = y, x >>> print(x, y, z) 2 1 3 ----------------------- >>> values = 1, 2, 3 >>> values (1, 2, 3) >>> x, y, z = values >>> x 1 --------------------- # 在字典中的应用 >>> scoundrel = {'name': 'Robin', 'girlfriend': 'Marion'} >>> key, value = scoundrel.popitem() >>> key 'girlfriend' >>> value 'Marion' >>> key, value = scoundrel.popitem()
要解包的序列包含的元素个数必须与你在等号左边列出的目标个数相同,否则将引发异常。
👇可以使用 * 来收集多余的值于一个列表中,这样无须确保值和变量个数相同:>>> a, b, *rest = [1, 2, 3, 4] >>> rest [3, 4] ------------------ # 还可以调整位置 >>> seq = "1 2 3 4 5" >>> first, *middle, last = seq.split() >>> middle ['2', '3', '4']
* 解 list 以及 ** 解 dict
列表
>>> print(*[1, 2, 3]) 1 2 3
字典
>>> def add(a,b,c): return a+b+c >>> d = {'a': 1, 'b': 2, 'c':3} >>> add(*d) # 对于字典,默认解包对象是“键” 'abc' >>> add(*d.values()) 6
>>> def seperate(a,b,c,d): print(a) print(b) print(c) print(d) >>> d = {'a':1,'b':2,'c':3,'d':4} >>> seperate(*d.items()) ('a', 1) ('b', 2) ('c', 3) ('d', 4)
>>> def add(a,b,c): print(a) print(b) print(c) return a+b+c d = {'a':1,'b':2,'c':3} >>> add(**d) # ** 对字典的所有值进行解包,但是!!!该字典的所有键必须为字符串类型 1 2 3 6 >>> d_false = {1:'a',2:'a',3:'a'} >>> add(**d_false) Traceback (most recent call last): File "<pyshell#102>", line 1, in <module> add(**d_false) TypeError: add() keywords must be strings
注意!!!“*”不能直接使用,必须结合相应函数或表达式运算👇
>>> *[1, 2, 3, 4] SyntaxError: can't use starred expression here >>> *range(4) SyntaxError: can't use starred expression here >>> *range(4), 4 (0, 1, 2, 3, 4) >>> *[1,2,3,4],5 (1, 2, 3, 4, 5)
** 字典解析(仅适用于函数传参)
>>> def people(greeting, **info): # ** 仅能以关键字参数的形式传值 print(greeting) print(info) >>> people('Hello', xiaoming='student', lihua='manager', zhangsan='ambassdar') Hello {'xiaoming': 'student', 'lihua': 'manager', 'zhangsan': 'ambassdar'}
约定:
- 定义函数时,函数名仅使用小写字母和下划线
- 使用关键字参数传值时,等号“=”两边不要有空格符
- 定义的函数需在开头写明注释,采用文档字符串格式
2.2.2 链式赋值
- x = y = somefunction()
等价于👇
y = somefunction()
x = y
可能不等价于👇
x = somefunction()
y = somefunction()
2.2.3 增强赋值
即类似于"x +=1"、“x /=2”
2.3 缩进
- 代码块:是一组语句,可在满足条件时执行,可执行多次,等等。是通过缩进代码来创建的。
在Python中,使用冒号( :)指出接下来是一个代码块,并将代码块中的每行代码缩进相同程度。
2.4 条件和条件语句
2.4.1 布尔值(真值)
标准布尔值:True(相当于1)、False(相当于0)
👇下面的值都将被解释器视作假:
>>> bool(0)
False
>>> bool([])
False
>>> bool(None)
False
- all(iterable, /)
Return True if bool(x) is True for all values x in the iterable.
If the iterable is empty, return True.>>> all([1, 'a', 'k', 8, 'hello']) True >>> all([0]) False >>> all("") True >>> all([""]) False >>> all({}) True
2.4.2 条件语句
- if 语句: if - elif - else
- 条件表达式: A if < 表达式 > else B —— 相当于C语言中的三目运算符 < 表达式 >? A:B
nums = "123456" >>> k = 1 if nums.endswith('6') else 2 >>> k 1
2.4.3 比较运算符
★Python支持链式比较,即同时使用多个比较运算符:
>>> 1<=2<=3
True
- is:相同运算符
is 检查两个对象是否相同(而不是相等)
>>> x = y = [1,2,3]
>>> z = [1,2,3]
>>> x == y
True
>>> x == z
True
>>> x is y
True
>>> x is z
False
小结:== 用来检查两个对象是否相等,而 is 用来检查两个对象是否相同(是同一个对象)
- 布尔运算符:
and(相当于C语言中 && ) 、 or(相当于 | ) 、 not(相当于 ! )>>> ((2 > 1) or 0) and not 0 True
2.5 断言 assert
-
让程序出现错误立即崩溃胜过以后再崩溃
>>> age = 10 >>> assert 0 < age < 100 >>> age = -1 >>> assert 0 < age < 100 Traceback (most recent call last): File "<pyshell#27>", line 1, in <module> assert 0 < age < 100 AssertionError # 可在条件后面添加字符串,对断言做出说明。 >>> assert 0 < age < 100,'The age must be realistic' Traceback (most recent call last): File "<pyshell#28>", line 1, in <module> assert 0 < age < 100,'The age must be realistic' AssertionError: The age must be realistic
try:
assert 1==2,”1 is not equal 2!”
except AssertionError as reason:
print(“%s:%s”%(reason.__class__.__name__, reason))
AssertionError:1 is not equal 2!
2.6 循环
2.6.1 while 循环
使用循环来确保用户输入名字:
name = ''
while not name:
name = input('Please enter your name: ')
print('Hello, {}!'.format(name))
如果仅输入空格字符,将会输出:
Please enter your name:
Hello, !
因为包含一个空格符的字符串不是空的,可将while not name改为*while not name or name.isspace()或while not name.strip()*解决:
name = ''
# while not name or name.isspace():
while not name.strip():
name = input('Please enter your name: ')
print('Hello, {}!'.format(name))
2.6.2 for 循环
>>> for i in range(1,20):
print(i, end = ',')
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,
for循环比while循环更紧凑,能用for,不用while
- 要注意循环次数!
e.g.👇当执行三次后,列表中只剩三个元素,不能满足遍历第四个元素了
for 语句可以使用 for i in range(len(ss)) 替代,来避免错误>>> ss = [2,3,6,9,7,1] >>> for i in ss: print(max(ss),end=',') ss.remove(max(ss)) 9,7,6,
2.6.3 迭代字典
>>> d = {'x': 1, 'y': 2, 'z': 3}
>>> for key in d:
print(key, 'corresponds to', d[key])
x corresponds to 1
y corresponds to 2
z corresponds to 3
for循环优点之一就是可在其中使用序列解包:
>>> for key, value in d.items():
print(key, 'corresponds to', value)
x corresponds to 1
y corresponds to 2
z corresponds to 3
2.6.4 一些迭代工具
- 并行迭代
- 函数zip() —— 他将两个序列“缝合”起来,返回一个由元组组成的序列。
返回值是一个适合迭代的对象,要查看其内容,可使用list将其转换为列表。
“缝合”后,可在循环中将元组解包:>>> names = ['anne', 'beth', 'george', 'damon'] >>> ages = [12, 45, 32, 102] >>> list(zip(names, ages)) [('anne', 12), ('beth', 45), ('george', 32), ('damon', 102)]
注:当序列的长度不同时,函数zip将在最短的序列用完后停止缝合。>>> for name, age in zip(names, ages): print(name, 'is', age, 'years old') anne is 12 years old beth is 45 years old george is 32 years old damon is 102 years old
- 迭代式获取索引
实例:替换一个字符串列表中所有包含子串 ‘789’ 的字符串
- 方法1:先找到含指定子串的字符串的索引index,然后利用索引index进行替换
>>> strings = ['123', '456', '789'] >>> for string in strings: if '789' in string: index = strings.index(string) strings[index] = '11 12 13' >>> strings ['123', '456', '11 12 13']
- 方法2:直接初始化序号index=0,序号的值随着每一次迭代递增,直到找到该字符串为止,此时index值即为该字符串的索引。
>>> strings = ['123', '456', '789'] >>> index = 0 >>> for string in strings: if '789' in string: strings[index] = '11 12 13' index += 1 >>> strings ['123', '456', '11 12 13']
- 方法3:利用内置函数enumerate。在迭代索引-值时,其中的索引时自动提供的。
>>> strings = ['123', '456', '789'] >>> for index, string in enumerate(strings): if '789' in string: strings[index] = '11 12 13' >>> strings ['123', '456', '11 12 13']
- 反向迭代和排序后再迭代
- reversed 和 sorted:
reversed 和 sorted类似于列表方法 reverse 和 sort,但可用于任何序列或可迭代的对象,且不就地修改对象。-
sorted
>>> a = [9,5,4,2,7,8] >>>> a.sort() >>> a [2, 4, 5, 7, 8, 9]
👆对比操作方法及特性👇
>>> a = [9,5,4,2,7,8] >>> sorted(a) [2, 4, 5, 7, 8, 9] >>> a [9, 5, 4, 2, 7, 8]
-
reversed
>>> a = ['9','5','4','2','7','8'] >>> a.reverse() >>> a ['8', '7', '2', '4', '5', '9']
👆对比操作方法及特性👇
>>> a = ['9','5','4','2','7','8'] >>> reversed(a) <list_reverseiterator object at 0x0000027697435820> >>> a ['9', '5', '4', '2', '7', '8'] >>> list(reversed(a)) ['8', '7', '2', '4', '5', '9'] >>> a ['9', '5', '4', '2', '7', '8'] >>> ''.join(list(reversed(a))) '872459'
join是字符串方法。
补充:若要按字母排序,可先转换为小写。为此,可将sort或sorted的key参数设置为str.lower
>>> sorted('aBc', key = str.lower) ['a', 'B', 'c']
-
2.6.5 跳出循环
- break
- continue
2.7 列表推导
列表推导是一种从其他列表创建列表的方式,类似于数学中的集合推导。
[x * x for x in range(10)]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
若只想打印能被3整除的平方值:
>>> [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(3)]
[(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]
对比常规的两层写法简便些。
- 实例:
将名字首字母相同的男孩和女孩配对。>>> girls = ['alice', 'bernice', 'clarice'] >>> boys = ['chris', 'arnold', 'bob'] >>> [b+'+'+g for b in boys for g in girls if b[0] == g[0]] ['chris+clarice', 'arnold+alice', 'bob+bernice']
2.8 pass、del 和 exec
2.8.1 pass
-
pass:即什么都不做。
应用场景:Python不允许代码块为空,在编写程序时,可将其用作占位符。
if n == 1: print('OK') elif n == 2: # 还未完成··· pass else: # 还未完成··· pass
2.8.2 del
- del
略
补充:垃圾收集,即Python解释器将计算机内存中无名称关联的对象删除。
2.8.3 exec
-
exec
函数exec将字符串作为代码执行>>> exec("print('Hello, world!')") Hello, world!
然而,在大多数情况下,还应向他传递一个命名空间(用于放置变量的地方),否则代码将污染你的命名空间,即修改你的变量。
>>> from math import sqrt >>> exec("sqrt = 1") >>> sqrt(4) Traceback (most recent call last): File "<pyshell#82>", line 1, in <module> sqrt(4) TypeError: 'int' object is not callable
函数exec主要用于动态地创建代码字符串,如果这种字符串来自其他地方(可能是用户),就几乎无法定它包含什么内容。因此,为了安全起见,要提供一个字典充当命名空间。
>>> from math import sqrt >>> scope = {} >>> exec('sqrt = 1',scope) >>> sqrt(4) 2.0 >>> scope['sqrt'] 1
如果尝试将scope打印出来,会发现它包含很多内容,是因为自动在其添加了包含所有内置函数和值的字典__builtins__
>>> len(scope) 2 >>> scope.keys() dict_keys(['__builtins__', 'sqrt'])
2.9 异常处理结构
异常处理是指因为程序执行过程中出错而在正常控制流之外采取的行为。
作用:熟练运用异常处理机制对于提高程序的健壮性和容错性具有重要的作用,同时也可以把python晦涩难懂的错误提示转换为友好的提示显示给最终用户。
2.9.1 try……except结构
结构语法
try:
try 块
except Exception[As reason]:
except 块
一般建议有针对性地进行异常处理~
2.9.2 try……except……else结构
当 try 中的代码没有任何异常,则跳过 except 块执行 else 中的代码。
2.9.3 带有多个except的try结构
如果确定要捕获的多个异常可以使用同一段代码来处理,则可仅使用一个except并将要捕获的异常写在一个元组中。
2.9.4 try……except……finally结构
在该结构中,无论是否发生异常,finally 中的语句块都会执行,常用来做一些清理工作以释放 try 子句中申请的资源。
需要注意的是,如果try子句中的异常没有被捕捉和处理,或者except子句或else子句中的代码出现了异常,那么这些异常将会在finally子句执行完后再次抛出。
try:
3/0
finally:
print(5)
5
ZeroDivisionError:division by zero