欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

第五章_条件、循环和其他语句

程序员文章站 2022-06-15 19:22:26
...

温馨提示:在本章的代码中,除了代码前有>>>提示符的代码可以在python解释器中执行外,其余代码一律需要保存为.py结尾的文件以后再执行。
附:IDE下载

5.1print和import的更多信息

5.1.1使用逗号输出

打印多个表达式,表达式之间用逗号分隔,打印的时候print会将每个表达式参数之间加入空格
>>> print 'age',42
age 42
#print 打印元组必须加括号
>>> print 1,2,3
1 2 3
>>> print (1,2,3)
(1, 2, 3)
>>> 1,2,3
(1, 2, 3)
>>> 
如果在结尾处加上逗号,那么接下来的语句会与前一条语句在同一行打印
>>>
>>>print 'Hello',
>>>print 'World'
Hello,World

5.1.2把某一事件作为另一事件导入

从模块导入事件的方式
import somemodule

from somemodule import somefunction

from somemodule import somefunction,anotherfunction,yetanotherfunction

frome somemodule import  * #从给定模块导入所有的功能

如果两个模块都有同名函数open,怎么办?
#方法一
module1.open()
module2.open()
#方法二,为模块起别名
>>> import math as foobar
>>> foobar.sqrt(4)
2.0
>>> 
#方法三,为函数起别名
>>> from math import sqrt as foobar
>>> foobar(4)
2.0
>>> 

5.2赋值魔法

就算是一个不起眼的赋值语句也有一些特殊的技巧

5.2.1序列解包(递归解包)
将多个值的序列解开,然后放到变量的序列中
条件是,解包的序列中的元素数量必须和放置在赋值符号=左边的变量数量完全一致,否则Python会在赋值时引发异常

多个赋值可以同时进行
>>> x,y,z = 1,2,3
>>> print x,y,z
1 2 3
#可用于交换两个变量的值
>>> x,y=y,x
>>> print x,y,z
2 1 3

5.2.5链式复制:将同一个值赋给多个变量的捷径

x=y=somefunction()
等同于
y=somefunction()
x=y

5.2.3增量赋值

>>> x=2
>>> x+=1
>>> x*=2
>>> x
6
#字符串也适用
>>> fnoord = 'foo'
>>> fnord = 'foo'
>>> fnord+='bar'
>>> fnord*=2
>>> print fnord
foobarfoobar
>>> 

5.3语句块:缩排的乐趣

语句块:语句块是在条件为真时执行或者执行多次的一组语句。在代码前放置空格来缩进语句即可创建语句块

规则:

(1)块中的每行都应该缩进同样的量
(2)Python中,冒号(:)用来标识语句块的开始,块中的每一个语句都是缩进的(缩进量相同)。当退回到和已经闭合的块一样的缩进量时,就表示当前块已经结束了

5.4条件和条件语句

5.4.1这就是布尔变量的作用

真值也叫做布尔值

下面的值在作为布尔表达式的时候,会被解释器看做假(false)

False、None、0、()、[]、{}
一句话概括:标准值False和None,所有类型的数字0、空序列、空字典都为假。其他的一切都被解释为真,包括特殊值True

bool()函数

用来将其他值转换成布尔值
>>> b = bool("Hello World")
>>> b
True
>>> bool(42)
True
>>> bool('')
False
>>> bool(0)
False
>>> 

5.4.2条件执行和if语句

name = raw_input('What is your name?')
if name.endswith("Gumby"):
        print "Hello Mr.Gumby"

5.4.3else子句

为什么叫子句:因为它不是独立的的语句,而自能作为if语句的一部分
name = raw_input('What is your name?')
if name.endswith("Gumby"):
        print "Hello Mr.Gumby"
else:
        print 'Hello stranger'

5.4.4elif子句

如果需要检查多个条件,就可以使用elif,它是else if的简写
num = input('Enter a number')
if num > 0 :
        print 'The number is positive'
elif num < 0 :
        print "The number is negative"
else :
        print 'The number is zero'
~                                         

5.4.5 嵌套代码块

if语句里面可以嵌套使用if语句
name = raw_input('What is your name?')
if name.endswith('Gumby'):
    if name.startswith('Mr.'):
        print 'Hello ,Mr Gumby'
    elif name.startswith('Mrs.'):
        print 'Hello ,Mrs.Gumby'
    else:
       print 'Hello,Gumby'
else:
    print 'Hello,stranger'

5.4.6 更复杂的条件

1、比较运算符:用来比较其他对象
2、python中比较运算符合赋值运算符一样是可以连接的
3、几个运算符可以连载一起使用,
age = 23
0<age<100
True

2、相等运算符==:如果想要知道两个东西是否相等

'foo'=='foo'
True
'foo'=='bar'
False

3、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判定两个对象是否“等同”(是否是同一个对象)

4、in成员资格运算符
5、字符串和序列比较

字符串可以按照字母顺序排列进行比较
>>> 'alpha'<'beta'
True
ord函数:用来查询一个字母的顺序值  
>>> ord('a')
97
>>> ord('A')
65
如果比较中要忽略大小写的区别,需要使用字符串方法upper()和lower()
>>> x="FNorD"
>>> y='fnORd'
>>> x==y
False
>>> x.lower() == y.lower() 
True
>>> x.upper() == y.upper()
True
>>> 
其他序列也可以用来比较,此时就不是按字母顺序进行比较了,而是按序列中元素类型,相应的大小规则,来进行比较
>>> [1,2]<[2,1]
True
>>> [2,1]<[1,2]
False
>>> [2]<[1]
False
>>> [1]<[2]
True

#序列中包含其他序列
>>> [2,[1,4]]<[2,[1,5]]
True
>>> 

6、布尔运算符

and or not
number = input('Enter a number between 1 and 10')
if number <= 10 and number >= 1:
    print "Greate"
else:
    print 'Wrong'
说明:布尔运算符的特性:只有在需求值时才进行求值。这种行为被称为短路逻辑或惰性求值(也就是如果同过布尔运算符前面的布尔表达式的值,就能判断出整个表达式的值,python就不会运算布尔运算符后面的布尔表达式)

5.4.7断言:assert

理论:与其让程序在晚些时候崩溃,不如在错误条件出现的时候直接让它崩溃

怎么使用

如果需要确保程序中的某一条件一定为真才能让程序正常工作的的话,assert就有用了
>>> age = 1
>>> assert 0 < age < 100,'The age must be relalistic' 
>>> age = -1
>>> assert 0 < age < 100,'The age must be relalistic' 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AssertionError: The age must be relalistic
>>> 
条件后可以通过在逗号后面添加字符串,用来解释断言 

5.5循环

现在你已经知道,条件为真时如何执行了,但是怎么才能执行多次呢?

5.5.1while循环

用来在任何条件为真的情况下重复执行一个代码块
x = 1
while x <= 100:
    print x
    x+=1
#确保用户输入名字
name = ''
while not name:
    name = raw_input("Please Enter your name!")
print 'Hello %s !' % name

5.5.2 for循环

可迭代对象:指可以按次序迭代的对象(像序列)
words = ['this','is','an','ex','parrot']
for word in words:
    print word
内建的范围函数range()
>>> range(0,10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> 
for number in range(1,101):
    print number
说明:包含的一个索引,但不包含第二个索引
提示:如果能使用for循环,就尽量不要使用while循环

补充

xrange函数的循环行为类似于range函数,区别在于range函数一次创建整个序列,而xrange一次只创建一个“数”,当需要迭代一个巨大的序列时xrange会更高效,不过一般情况下不需要过多关注它。

5.5.3循环遍历字典元素

d = {'x':1,'y':2,'z':3}
for key in d:
   print key,'corresponds to',d[key]
for循环的一个好处,就是可以在循环中使用序列解包
d = {'x':1,'y':2,'z':3}
for key,value in d.items():
    print key, 'corresponds to', value

5.5.4一些迭代工具

并行迭代:程序可以同时迭代两个序列

# i 索引的标准变量名
names = ['anne','beth','george','damon']
ages = [12 , 45 ,32 ,102]
for i in range(len(names)):
    print names[i],'is',ages[i],'years old'

内建zip函数:用来并行迭代,可以吧两个序列压缩在一起,然后返回一个元组列表

names = ['anne','beth','george','damon']
ages = [12 , 45 ,32 ,102]
for name,age in zip(names,ages):
    print name,'is',age,'years old'

zip函数也可以作用于任意多序列。并且可以处理不等长的序列,当最短的序列用完的时候就会停止
>>> zip(range(5),range(1000000))
[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)]

按索引迭代:enumerate函数:迭代序列中的对象的同时还需要获取当前对象的索引

这里写代码片

**翻转和排序迭代**reversed 和 sorted

可以作用于任何序列或可迭代对象上,但不是原地修改对象,而是返回翻转或排序后的副本
>>> sorted([4,3,6,8,3])
[3, 3, 4, 6, 8]
>>> sorted('Hello,World!')
['!', ',', 'H', 'W', 'd', 'e', 'l', 'l', 'l', 'o', 'o', 'r']
>>> list(sorted('Hello,World!'))
['!', ',', 'H', 'W', 'd', 'e', 'l', 'l', 'l', 'o', 'o', 'r']
>>> ''.join(sorted('Hello,World!'))
'!,HWdellloor'
>>>

5.5.5跳出循环
break

from math import sqrt
for n in range(99,0,-1):
    root = sqrt(n)
    if root == int(root):
        print n
        break
说明:range函数增加了第3个参数——表示步长,步长表示没队相邻数值之间的差别。将其设置为负值的话,就会反向迭代
#注意与分片操作的区别,
>>> range(99,0,-1)
[99, 98, 97, 96, 95, 94, 93, 92, 91, 90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 80, 79, 78, 77, 76, 75, 74, 73, 72, 71, 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1]

continue

含义:跳过剩余的循环体,但是不结束循环。
这里写代码片

while True/break习语

哑值(dummy value):未使用的值
word = 'dummy'
while word:
    word = raw_input('Please enter a word:')
    print 'The word was'+word
#避免使用哑值,但是有重复的代码
word = raw_input('Please enter a word:')
while word:
    print 'The word was'+word
    word = raw_input('Please enter a word:')
#while true/break 习语,没有哑值也没有重复语句
while True:
    word = raw_input('Please enter a word')
    if not word : break
    print 'The word was' + word

5.5.6循环中的else子句

5.6列表推导式——轻量级循环

列表推导式:是利用其它列表创建新列表的一种方法,它的工作方式类似于for循环。
例:
>>> [x*x for x in range(10)]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> 
含义:列表由range(10)中每个x的平方组成。
2#在列表推到式中添加if部分
>>> [x*x for x in range(10) if x % 3 == 0 ]
[0, 9, 36, 81]
>>> 
含义:打印在range(10)中那些只能被3整除的平方数
#增加更多的for语句
#range(10)和range(3)的笛卡尔积
>>> [(x,y) for x in range(10) for y in range(3)]
[(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2), (3, 0), (3, 1), (3, 2), (4, 0), (4, 1), (4, 2), (5, 0), (5, 1), (5, 2), (6, 0), (6, 1), (6, 2), (7, 0), (7, 1), (7, 2), (8, 0), (8, 1), (8, 2), (9, 0), (9, 1), (9, 2)]
#
>>> [(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)]
>>> 
#联合if语句使用
>>> [b+'+'+g for b in boys for g in girls if  b[0]==g[0]]
['chris+clarice', 'arnold+alice', 'bob+bernice']
>>> 
注意:使用普通的圆括号而不是方括号“不会”的到“元组推导式”

5.7三人行
5.7.1什么都没发生
pass:有的时候,程序什么事情都不用做,这种情况不多,但是一旦出现,就应该让pass语句出马

>>> pass
>>> 

作用:它可以在代码中做占位符使用
为什么:Python中空代码块是非法的
例:

#下面的程序不会执行
name=None
if name == 'Ralph Auldus Melish':
    print 'welcome'
elif name == 'enid':
    #空代码块
elif name == 'Bill Gates':
    print 'Access Denie'
#加上一个pass之后即可解决
  name=None
if name == 'Ralph Auldus Melish':
    print 'welcome'
elif name == 'enid':
    #空代码块加入pass
    pass
elif name == 'Bill Gates':
    print 'Access Denie'

5.7.2使用del删除

>>> scoundre1 = {'age':42,'first name':'Robin','last name':'of Locksley'}
>>> robin = scoundre1
>>> robin
{'last name': 'of Locksley', 'first name': 'Robin', 'age': 42}
>>> scoundre1
{'last name': 'of Locksley', 'first name': 'Robin', 'age': 42}
>>> scoundre1=None
>>> robin
{'last name': 'of Locksley', 'first name': 'Robin', 'age': 42}
>>> robin=None
>>> 
分析:robin 和 scounder 都被绑定到同一个字典上。所以当设置scoundre1位None的时候,字典通过robin还是可用的当把robin设置成None的时候,字典就飘在内存里面了。这时Python解释器会直接删除那个字典,这种行为被称为垃圾收集,注意,也可以使用None的其他值。

使用的del语句

功能:它不仅会移除一个对象的引用,也会移除那个名字本身
>>> x = 1
>>> del x
>>> x
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined
>>> 
看起来简单,但是有时理解起来有些难度
>>> x = ['Hello','world']
>>> y = x
>>> y[1] = 'Python'
>>> x
['Hello', 'Python']
>>> y
['Hello', 'Python']
>>> del x
>>> y
['Hello', 'Python']
>>> x
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined
>>> 
1.会有人认为删除x后,y也就随之消失,但事实并非如此。
2.事实上Python中是没有办法删除值的,也不需要考虑删除值的问题,因为在某个值不再使用的时候,Python解释器会负责内存的回收

5.7.4使用exec,eval执行和求值字符串
exec:执行一个字符串的语句是exec

>>> exec "print 'Hello,world'"
Hello,world
>>> 
1、使用简单形式的exec语句绝不是好事,很多情况下可以给它提供命名空间(可以放置变量的地方)
2、命名空间的概念,或称为作用域,是非常总要的知识

eval:类似于exec的内建函数。eval会计算Python表达式,并且返回结果值。而exec不会返回任何对象,因为它本身就是语句。


全文引用于:作者: Magnus Lie Hetland

出版社: 人民邮电出版社

原作名: Beginning Python: From Novice to Professional, Second Edition

译者: 司维 / 曾军崴 / 谭颖华

出版年: 2010-7

页数: 471

定价: 69.00元

装帧: 平装

丛书: 图灵程序设计丛书

ISBN: 9787115230270