title: 条件和循环语句 create: 2016.12.7 modified: 2016.12.7 tags: python 语句 列表推导式

  3

[TOC]

前面已经介绍过了几个基本语句(print语句、import语句、赋值语句)。接下来你会看到列表推导式(list comprehension)如何扮演循环和条件语句的角色。最后介绍pass、del和exec语句的用法。

1 语句块:缩排的乐趣

语句块是在条件为真(条件语句)时执行或者执行多次(循环语句)的一组语句。在代码前放置空格来缩进语句即可创建语句块。
注意 使用tab字符也可以缩进语句块。而一个tab字符位置为8个空格,但是标准且推荐的方式是只用空格,尤其是在每个缩进需要4个空格的时候

2 条件和条件语句

这部分会介绍让程序选择是否执行语句块的方法。

2.1 布尔变量的作用

下面的值在作为布尔表达式的时候,会被解释器看做假(false):
False None 0 "" () [] {}
其他的一切都被解释为真。
布尔值True和False属于布尔类型,bool函数(和list、str、tuple一样)可以用来转换其他值。


In [2]:
bool('ok')


Out[2]:
True

In [3]:
bool(8)


Out[3]:
True

In [4]:
bool('')


Out[4]:
False

2.2 条件执行和if语句、else子句、elif子句


In [7]:
num=input('Enter a number:')
if num>0:
    print 'positive'
elif num<0:
    print 'negative'
else:
    print 'zero'


Enter a number:8
positive

2.3 更复杂的条件

1. 比较运算符
x==y
x < y
x>=y
x!=y
x is y
x is not y(x和y是不同的对象)
x in y
x not in y(x不是y容器(例如,序列)的成员)
注意: 使用==运算符来判定两个对象是否相等,使用is判定两者是否等同(同一个对象)。

2. 布尔运算符
and, or, not就是所谓的布尔运算符。

3 循环

3.1 while循环


In [8]:
x=1
while x<=3:
    print x
    x+=1


1
2
3

3.2 for循环


In [9]:
nums=[1,2,3]
for n in nums:
    print n


1
2
3

因为迭代(循环的另外一种说法)某范围的数字是很常见的,所以有个内建的范围函数供使用:


In [10]:
range(0,10)


Out[10]:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

range函数的工作方式类似于分片。它包含下限,但不包含上限。如果希望下限为0,可以只提供上限:


In [11]:
range(10)


Out[11]:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

In [18]:
range(10,0,-2)  #-2表示步长


Out[18]:
[10, 8, 6, 4, 2]

3.3 循环遍历字典元素

一个简单的for语句就能循环字典的所有键:


In [12]:
d ={'x':1,'y':2,'z':3}
for key in d:
    print key,'corresponds to', d[key]


y corresponds to 2
x corresponds to 1
z corresponds to 3

如果只需要值,可以使用d.values替代d.keys。d.items方法会将键-值对作为元组返回,for循环的一大好处就是可以循环中使用序列解包:


In [13]:
for key, value in d.items():
    print key,'corresponds to', value


y corresponds to 2
x corresponds to 1
z corresponds to 3

3.4 翻转和排序迭代

reversed和sorted这两个函数同列表的reverse和sort方法类似,但能作用于任何序列或可迭代对象上,不是原地修改对象,而是返回翻转或排序后的版本:


In [14]:
sorted([4,3,6,8])


Out[14]:
[3, 4, 6, 8]

In [15]:
reversed([4,3,6,8])


Out[15]:
<listreverseiterator at 0x411ae48>

In [16]:
list(reversed([4,3,6,8]))


Out[16]:
[8, 6, 3, 4]

注意:虽然sorted函数返回列表,reversed函数却返回一个可迭代对象。它们大可在for循环以及join方法中使用,而不会有任何问题。不过却不能直接对它使用索引、分片及调用列表的方法。

3.5 并行迭代

程序可以同时迭代两个序列。比如有下面两个列表:


In [52]:
names=['anne','beth','george','damon']
ages=[12,45,32,102]
for i in range(len(names)):
    print names[i],'is',ages[i],'years old'


anne is 12 years old
beth is 45 years old
george is 32 years old
damon is 102 years old

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


In [53]:
zip(names,ages)


Out[53]:
[('anne', 12), ('beth', 45), ('george', 32), ('damon', 102)]

现在可以在循环中解包元组:


In [54]:
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

3.6 跳出循环

1. break
结束(跳出)循环可以使用break语句。
2. continue
continue会让当前的迭代结束,“跳”到下一轮循环的开始。

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

列表推导式(类似于数学术语中的集合推导式)是利用其他列表创建新列表的一种方法。它的工作方式类似于for循环:


In [19]:
[x*x for x in range(10)]


Out[19]:
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

如果只想打印出那些能被3整除的平方数呢?可以使用模除运算符—y%3。


In [20]:
[x*x for x in range(10) if x % 3 ==0]


Out[20]:
[0, 9, 36, 81]

In [21]:
[(x,y) for x in range(2) for y in range(3)]


Out[21]:
[(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2)]

5 pass、del和exec语句


In [23]:
pass    #该语句什么事情也不做

In [25]:
x=1
del x
x


---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-25-0ba4a8505457> in <module>()
      1 x=1
      2 del x
----> 3 x

NameError: name 'x' is not defined

del语句不仅会移除一个对象的引用,也会移除那个名字本身。

有些时候可能需要动态地创造Python代码,然后将其作为语句执行或作为表达式计算。而exec语句能执行存储在字符串中的Python代码。eval语句会计算Python表达式,并且返回结果值。


In [26]:
exec 'print "Hello, world"'


Hello, world

In [27]:
from math import sqrt
exec 'sqrt=1'
sqrt(4)


---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-27-fe92a6d219bc> in <module>()
      1 from math import sqrt
      2 exec 'sqrt=1'
----> 3 sqrt(4)

TypeError: 'int' object is not callable

exec语句最有用的地方在于可以动态地创造代码字符串。如果字符串是从其他地方获得的—很可能是用户—那么就不能确定其中到底包含什么代码。所以为了安全起见,可以增加一个字典,起到命名空间的作用。


In [28]:
from math import sqrt
scope={}
exec 'sqrt=1' in scope
sqrt(4)


Out[28]:
2.0

In [30]:
scope['sqrt']


Out[30]:
1

可以通过增加in scope来实现,其中scope就是起到放置代码字符串命名空间作用的字典。可以看到,潜在的破坏性代码并不会覆盖sqrt函数,原来的函数能正常工作,而通过exec赋值的变量sqrt只能在它的作用域内有效。


In [31]:
eval('6+18*2')  #执行表达式


Out[31]:
42

In [34]:
exec('x=6+18*2')  #执行语句
x


Out[34]:
42

6 小结


In [ ]: