第五章 条件、循环和其他语句
5.1 print和import
1、sep打印分割样式:
'''
print("a","b","c",sep="_")
'''
a_b_c
------------------
(program exited with code: 0)
请按任意键继续. . .
2、end打印的末尾格式
'''
print("a","b",end=(""))
print("a","b",end=("\t"))
print("a","b",end=("*"))
print("a","b",end=("\n"))
print("a","b","c",sep="_")
'''
a ba b a b*a b
a_b_c
------------------
(program exited with code: 0)
请按任意键继续. . .
其实,print是python的一个内置函数,它的参数可选,它的原函数为:
print(self, *args, sep=' ', end='\n', file=None)
#以下是原注释。
print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)
Prints the values to a stream, or to sys.stdout by default. #默认情况下,将值打印到流或sys.stdout文件。
Optional keyword arguments: #可选关键字参数:
file: a file-like object (stream); defaults to the current sys.stdout. #file: 一个类似文件的对象(流);默认为当前sys.stdout。
sep: string inserted between values, default a space. # sep:在输出字符串之间插入值 ,默认为空。
end: string appended after the last value, default a newline. #end:附加在最后一个值之后的字符串,默认为换行符。
flush: whether to forcibly flush the stream. #flush:是否强制输出流。(默认为False)
5.1.2 导入时重命名
从模块导入时,通常使用①import somemodule 或使用②from somemodule import somefunction 或
③from somemodule import somefunction, anotherfunction, yetanotherfunction 或④from somemodule import *
仅当你确定要导入模块中的一切时,采用使用最后一种方式。 如果有两个模块,包含同名函数,就第一种方式导入相应的模块,但还有一种办法:在语句末尾添加as子句并指定别名。下面是一个导入整个模块并给它指定别名的例子:
'''
import math as abcde
print(abcde.sqrt(9))
'''
指定abcde为math模块的别名。输出结果为:
3.0
------------------
(program exited with code: 0)
请按任意键继续. . .
也可以为导入的函数指定别名。
'''
from math import sqrt as abcd
print(abcd(9))
'''
3.0
------------------
(program exited with code: 0)
请按任意键继续. . .
5、赋值魔法
5.2.1序列解包
可同时(并行)给多个变量赋值:
'''
x,y,z,=2,3,4
print(x,y,z,
)
'''
2 3 4
------------------
(program exited with code: 0)
请按任意键继续. . .
使用这种方式还可交换多个变量的值。
'''
x,y,z=z,y,x
print(x,y,z)
'''
4 3 2
------------------
(program exited with code: 0)
请按任意键继续. . .
实际上,这里执行的操作称为序列解包(或可迭代对象解包):将一个序列(或任何可迭代对象)解包,并将得到的值存储到一系列变量中。
这在使用返回元组(或其他序列或可迭代对象)的函数或方法时很有用。假设要从字典中随便获取(或删除)一个键-值对,可使用方法popitem,它随便获取一个键-值对并以元组的方式返回。接下来,可直接将返回的元组解包到两个变量中。
这让函数能够返回被打包成元组的多个值,然后通过一条赋值语句轻松地访问这些值。要解包的序列包含的元素个数必须与你在等号左边列出的目标个数相同,否则Python将引发异常。
'''
sc={"a":10,"b":20,"c":30}
print(sc.popitem())
k,v=sc.popitem()
print(k,v)
'''
('c', 30)
b 20
------------------
(program exited with code: 0)
请按任意键继续. . .
但是,可使用星号运算符(*)来收集多余的值,这样无需确保值和变量的个数相同。*可以放在任何位置上。
'''
a,b,*c=[1,2,3,4,5,6]
print(*c)
names="张三 李四 王五 马六 刘七"
i,*j,k=names.split()
print(j)
'''
3 4 5 6
['李四', '王五', '马六']
------------------
(program exited with code: 0)
请按任意键继续. . .
5.2.2链式赋值
链式赋值是一种快捷方式,用于将多个变量关联到同一个值,形如:x=y=z=modeFun()
5.2.3 增强赋值
即:x+=2,x*=3,x/=1等等。
5.3代码块
在有些编程语言中代码块是用一对大括号({})表示的,在python中代码块是通过缩进代码(即在前面加空格)来创建的。使用冒号:指出接下来是一个代码块,并将该代码块中的每行代码都缩进相同的程度。发现缩进量与之前相同时,你就知道当前代码块到此结束了。
5.4 条件语句
5.4.1 布尔值
在python中false None 0 "" () [] {}被视为假,其他各种值都被视为真。标准的布尔值当然仍是0,1或False,True。
布尔值True和False属于类型bool,而bool与list、str和tuple一样,可用来转换其他的值.
5.4.2 if语句
格式为
if 条件:
条件为True时执行的语句
5.4.3 else子句
格式为:
if 条件:
条件为True时执行的语句
else:
条件为False时执行的语句
'''
s=["a","b","c"]
print(s)
if s[2]=="c" :
print("序列s的第二项是c")
else:
print("序列s的第二项不是c")
if s[2]==c:
print("序列s的第二项是c")
else:
print("序列s的第二项不是c")
'''
序列s的第二项是c
序列s的第二项不是c
------------------
(program exited with code: 0)
请按任意键继续. . .
5.4.4 elif子句
要检查多个条件,可使用elif子句。
'''
num=int(input("请输入一个数:"))
if num<0:
print("这个数小于零")
elif num>0:
print("这个数大于零")
else:
print("你输入了零!")
'''
请输入一个数:-1
这个数小于零
------------------
(program exited with code: 0)
请按任意键继续. . .
还有一个与if语句很像的“亲戚”,它就是条件表达式——C语言中三目运算符的Python版本。使用if和else确定其值:
格式为: 条件为True时执行的代码 if 条件 else 条件为False时执行的代码
5.4.5 代码嵌套
代码嵌套,按照代码缩紧的程度和顺序体现。
5.4.6运算符
i、算术运算符。
+、(加),-、(减),*、(乘),**、(幂),/、(除),//、(整除——商无小数),%(求余);乘法用于字符串。
'''
print("张三"*10)
'''
张三张三张三张三张三张三张三张三张三张三
------------------
(program exited with code: 0)
请按任意键继续. . .
ii、比较运算符。
==(等),>(大于),<(小于),>=(大于等于),<=(小于等于),!=(不等于)。
iii、赋值运算符。
=,+=,-=,*=,**=,/=,//=,%=等。
iv、逻辑运算符。
and(并且)、or(或者)、not(非)
v、位运算符。
&(与)、|(或)、~(非)、^(异或)、<<(左移)>>(右移)
vi、条件运算符。
格式为: 条件为True时执行的代码 if 条件 else 条件为False时执行的代码
vii、成员运算符。
in(是其序列的成员),not in (不是其序列的成员)
viii、身份运算符。
is (是同一个),is not(不是同一个)。
值得注意的是在python中有些运算符的使用有其自身特点。
1、字符串和序列可以比较:
'''
print("alpha">"bate")
'''
False
------------------
(program exited with code: 0)
请按任意键继续. . .
虽然基于的是字母排列顺序,但字母都是Unicode字符,它们是按码点排列的。要获悉字母的顺序值,可使用函数ord。这个函数的作用与函数chr相反。
'''
print(ord("a"))
print(ord("b"))
'''
97
98
------------------
(program exited with code: 0)
请按任意键继续. .
'''
print(chr(128584))
'''
?
------------------
(program exited with code: 0)
请按任意键继续. . .
2、与赋值一样,Python也支持链式比较:可同时使用多个比较运算符,如0 < age < 100。
'''
n=9
if 0
'''
这个数在一到十之间)
------------------
(program exited with code: 0)
请按任意键继续. . .
5.4.7断言:assert关键字
if语句有一个很有用的“亲戚”,其工作原理类似于下面的伪代码:
if 不满足自定义的条件
就抛出错误
用assert设定一定的条件,如果条件满足则程序继续执行否则程序终止执行,并抛出AssertionError错误。
如果使程序必须满足特定条件,才能正确地运行,就可以在程序中添加assert语句充当检查点,帮助检测程序。还可在条件后面添加一个字符串,对断言做出说明。
'''
a=3
b=4
print("*"*80)
assert a
'''
******************************************************************************
程序正常
7
Traceback (most recent call last):
File "xx.py", line 9, in
assert a
值得注意的是,断言抛出的是错误,不是异常,而这种错误出现是人们设定的。
5.5循环
5.5.1 while循环
格式:while 条件 :
需要循环执行的程序
'''
x=1
while x<=100:
print(x,end=("\t"))
x+=1
'''
1 2 3 4 5 6 7 8 9 10
11 12 13 14 15 16 17 18 19 20
21 22 23 24 25 26 27 28 29 30
31 32 33 34 35 36 37 38 39 40
41 42 43 44 45 46 47 48 49 50
51 52 53 54 55 56 57 58 59 60
61 62 63 64 65 66 67 68 69 70
71 72 73 74 75 76 77 78 79 80
81 82 83 84 85 86 87 88 89 90
91 92 93 94 95 96 97 98 99 100
------------------
(program exited with code: 0)
请按任意键继续. . .
5.5.2 for循环
格式:for 值 in 对象(常见的为序列——集合):
循环
'''
numbers=[0,1,2,3,4,5,6,7,8,9,10]
for number in numbers:
print(number,end=("\t"))
'''
0 1 2 3 4 5 6 7 8 9
10
------------------
(program exited with code: 0)
请按任意键继续. . .
鉴于迭代(也就是遍历)特定范围内的数是一种常见的任务,Python提供了一个创建范围的内置函数range。
'''
print()
ra=range(0,10)
ls=list(ra)
print(ls)
'''
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
------------------
(program exited with code: 0)
请按任意键继续. . .
'''
for i in range(1,101):
print(i,end=("\t"))
'''
1 2 3 4 5 6 7 8 9 10
11 12 13 14 15 16 17 18 19 20
21 22 23 24 25 26 27 28 29 30
31 32 33 34 35 36 37 38 39 40
41 42 43 44 45 46 47 48 49 50
51 52 53 54 55 56 57 58 59 60
61 62 63 64 65 66 67 68 69 70
71 72 73 74 75 76 77 78 79 80
81 82 83 84 85 86 87 88 89 90
91 92 93 94 95 96 97 98 99 100
------------------
(program exited with code: 0)
请按任意键继续. . .
5.5.3 迭代字典
'''
d={"a":1,"y":2,"z":3}
for key in d:
print(key,"__",d[key])
'''
a __ 1
y __ 2
z __ 3
------------------
(program exited with code: 0)
请按任意键继续. . .
也可以使用keys获取所有键,用values获取值。用items以元组的形式发明回键值对。for循环的优点之一就是可以给序列解包。
'''
for k,v in d.items():
print(k,"***",v)
'''
a *** 1
y *** 2
z *** 3
------------------
(program exited with code: 0)
请按任意键继续. . .
5.5.4一些迭代工具
1、并行迭代
同时迭代两个序列。
'''
names=["张三","李四","王五","马六"]
ages=[20,25,23,26]
for i in range(len(names)):
print(names[i],"的年龄是",ages[i],"岁。")
'''
张三 的年龄是 20 岁。
李四 的年龄是 25 岁。
王五 的年龄是 23 岁。
马六 的年龄是 26 岁。
------------------
(program exited with code: 0)
请按任意键继续. . .
有一个很有用的并行迭代工具是内置函数zip,它将两个序列“缝合”起来,并返回一个由元组组成的序列。返回值是一个适合迭代的对象,要查看其内容,可使用list将其转换为列表。
'''
lis=list(zip(names,ages))
print(lis)
for n,ag in lis:
print(n,"的年龄是",ag,"岁")
'''
[('张三', 20), ('李四', 25), ('王五', 23), ('马六', 26)]
张三 的年龄是 20 岁
李四 的年龄是 25 岁
王五 的年龄是 23 岁
马六 的年龄是 26 岁
------------------
(program exited with code: 0)
请按任意键继续. . .
需要指出的是,当序列的长度不同时,函数zip将在最短的序列用完后停止“缝合”。
2、迭代时获取索引——enumerate函数
enumerate函数是python的内置函数,用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标。
'''
strs=["张三","李四","王五"]
s=list(enumerate(strs))
print (s)
'''
[(0, '张三'), (1, '李四'), (2, '王五')]
------------------
(program exited with code: 0)
请按任意键继续. . .
'''
for i,st in s:
print(i,"__",st)
'''
0 __ 张三
1 __ 李四
2 __ 王五
------------------
(program exited with code: 0)
请按任意键继续. . .
'''
stri="这件事不错"
print(enumerate(stri))
print(list(enumerate(stri)))
'''
[(0, '这'), (1, '件'), (2, '事'), (3, '不'), (4, '错')]
------------------
(program exited with code: 0)
请按任意键继续. . .
由此,可以看出enumerate函数是把列表或字符串的索引和元素组成了多个元组的集合(序列)。而这个序列被list定义后便组成了一个有序的元组的列表。
由于字典是由键值对组成的序列,不是单一元素所以不能直接用这种方法遍历,即使遍历也只能是enumerate函数强加的索引和键组成的元组的列表,而漏掉了字典的值。
'''
dic={"张三":89,"李四":98,"王五":67}
print(dic)
li=list(enumerate(dic))
print(li)
for x,(y,z) in enumerate(dic):
print(x,y,z)
'''
{'张三': 89, '李四': 98, '王五': 67}
[(0, '张三'), (1, '李四'), (2, '王五')]
0 张 三
1 李 四
2 王 五
------------------
(program exited with code: 0)
请按任意键继续. . .
书中举了一个实例,是关于字符串替换的,但只是伪代码,没有实现,现以代码示例:
'''
print (strs)
for i, strin in enumerate(strs):
if "张" in strin:
strs[i]="刘六"
print(strs)
'''
['张三', '李四', '王五']
['刘六', '李四', '王五']
------------------
(program exited with code: 0)
请按任意键继续. . .
3、反向迭代和排序后再迭代
两个很有用的函数:reversed和sorted。它们类似于列表方法reverse(反转)和sort(排序)。
'''
li_s=[4,2,5,6,1,8,7]
print(sorted(li_s))
print(reversed(li_s))
print(list(reversed(li_s)))
print("".join(str(reversed(li_s))))
str_s="Hello,world!"
print(sorted(str_s))
print(reversed(str_s))
print(list(reversed(str_s)))
print("".join(reversed(str_s)))
'''
[1, 2, 4, 5, 6, 7, 8]
[7, 8, 1, 6, 5, 2, 4]
['!', ',', 'H', 'd', 'e', 'l', 'l', 'l', 'o', 'o', 'r', 'w']
['!', 'd', 'l', 'r', 'o', 'w', ',', 'o', 'l', 'l', 'e', 'H']
!dlrow,olleH
------------------
(program exited with code: 0)
请按任意键继续. . .
"sorted返回一个列表,而reversed像zip那样返回一个更神秘的可迭代对象。你无需关心这到底意味着什么,只管在for循环或join等方法中使用它,不会有任何问题。只是你不能对它执行索引或切片操作,也不能直接对它调用列表的方法。要执行这些操作,可先使用list对返回的对象进行转换。"
5.5.5跳出循环
1、break
要结束(跳出)循环,可使用break。
'''
from math import sqrt
for n in range(99,0,-1):
r=sqrt(n)
if r==int(r):
print(n,end="\t")
'''
81 64 49 36 25 16 9 4 1
------------------
(program exited with code: 0)
请按任意键继续. . .
'''
for n1 in range(99,0,-1):
r1=sqrt(n1)
if r1==int(r1):
print("\n",n1,end="\t")
break
'''
81
------------------
(program exited with code: 0)
请按任意键继续. . .
2、continue
它结束当前迭代,并跳到下一次迭代开头。这基本上意味着跳过循环体中余下的语句,但不结束循环。
'''
str_i=[1,2,3,4,5,6]
for n2 in str_i:
if n2==5:
continue
print("\n",n2)
'''
1
2
3
4
6
------------------
(program exited with code: 0)
请按任意键继续. . .
3、while True/break
'''
i=0
while i<10:
i+=1
if i==5:
print(i)
break
'''
5
------------------
(program exited with code: 0)
请按任意键继续. . .
5.5.6循环中的else子句
'''
j=0
for n1 in range(99,81,-1):
r1=sqrt(n1)
if r1==int(r1):
print("\n",n1,end="\t")
break
else:
print("没有找到!")
'''
没有找到!
------------------
(program exited with code: 0)
请按任意键继续. . .
这里else和for语句是并列关系,而不是if。无论是在for循环还是while循环中,都可使用continue、break和else子句。
5.6 简单推导
列表推导是一种从其他列表创建列表的方式,类似于数学中的集合推导。列表推导的工作原理非常简单,有点类似于for循环。
'''
li_s=[x*x for x in range(5)]
print(li_s)
'''
[0, 1, 4, 9, 16]
------------------
(program exited with code: 0)
请按任意键继续. . .
由此可以看出,推导就是按照一定的关系(结构)把一个序列(集合)中的元素提取出来再根据一定的条件组合成新的序列(集合)的方法(此处方法是指广义的方法而不是程序语言)。
其结构可以理解为:[指定所取出元素的关系 for 元素 in 原序列 if 条件]其中条件是可选的。
'''
li_st={i**2 for i in range(5) if i!=2}
print(li_st)
'''
{0, 1, 9, 16}
------------------
(program exited with code: 0)
请按任意键继续. . .
可以添加更多的for
'''
st_p=["张三","李四","王五","马六","刘七"]
ints=[89,41,50,78,67]
set_d={t:i for t in st_p for i in ints}
print(set_d)
'''
{'张三': 67, '李四': 67, '王五': 67, '马六': 67, '刘七': 67}
------------------
(program exited with code: 0)
请按任意键继续. . .
元组不能实现推导,而字典可以:
'''
scores={k:"{}的成绩是{}分".format(k,set_d[k])for k in set_d}
print(scores["张三"] )
'''
张三的成绩是67分
------------------
(program exited with code: 0)
请按任意键继续. . .
5.7 三人行
pass、del和exec语句
5.7.1 什么都不做——pass
'''
print("下面是pass")
pass
print("上面是pass")
'''
下面是pass
上面是pass
------------------
(program exited with code: 0)
请按任意键继续. . .
pass作为占位符使用
'''
for i in range(5):
if i==3:
pass
print(i)
'''
0
1
2
3
4
------------------
(program exited with code: 0)
请按任意键继续. . .
5.7.2 使用del——删除
5.7.3使用exec和eval
函数exec主要用于动态地创建代码字符串。通常为了安全起见,在使用exec是还必须有一个充当命名空间的字典参数。
1、exec
'''
scope={}
exec("sqrt=9",scope)
print(sqrt(4))
print(scope["sqrt"])
'''
2.0
9
------------------
(program exited with code: 0)
请按任意键继续. . .
这个例子中如果去掉exec的第二个参数,它将会干扰sqrt函数的执行,而抛出错误。
2、eval
eval是一个类似于exec的内置函数。与exec一样,也可向eval提供一个命名空间。exec执行一系列Python语句,而eval计算用字符串表示的Python表达式的值,并返回结果(exec什么都不返回,因为它本身是条语句)。
'''
scopes={}
exec('x=2',scopes)
ss=eval('x**x',scopes)
print(ss)
'''
4
------------------
(program exited with code: 0)
请按任意键继续. . .
(待续)