这章的主题是“条件、循环和其他语句”。主要介绍if for之类的语句的使用,能大大丰富可以做的事情。
赋值魔法
序列解包
多个赋值操作可以同时进行:
>>> 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'
所解包的序列中的元素数量必须和放置在赋值符号左边的变量数量完全一致,否则会引发异常。
增量赋值
可以将x = x + 1 写成x += 1。这种写法叫做增量赋值。
使用下面的代码:
>>> x = 2
>>> x += 1
>>> x *=2
>>> x
6
语句块
语句块是条件为真时执行或执行多次的一组语句。在代码前放置空格来锁紧语句即可创建语句块。
标准且推荐的方式是使用空格,每个缩进为4个空格。
Python中,冒号(:)用来标识语句块的开始,块中的每一个语句都是缩进的。当回退到已经闭合的块一样的缩进量是,表示当前块已经结束了。
条件和条件语句
布尔变量
下面的值在作为布尔表达式的时候,会被解释器看作假(False):
False None 0 “” [] {}
其他的一切解释为真(True)
elif子句
如果需要检查多个条件,就可以使用elif。
使用下面的代码:
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'
if语句可以嵌套使用。
几个比较特殊的比较运算符
表达式 | 描述 |
---|---|
x is y | x和y是同一个对象 |
x is not y | x和y不是同一个对象 |
x in y | x是y容器的成员 |
x not in y | x不是y容器的成员 |
连接两个逻辑判断
可以使用布尔运算符and or not连接两个布尔值。
使用下面的代码:
if((cash > price) or customer_has_good_credit_ and not out_of_stock:
give_goods()
断言
需要断言的原因
与其让程序在晚些时候崩溃,不如在错误条件出现时直接让它崩溃。一般来说你可以要求某些条件必须为真。语句中使用的关键字是assert。
如果需要确保程序中的某个条件一定为真才能让程序正常工作的话,assert语句就有用了,它可以在程序中植入检查点。
使用下面的代码:
>>> age=-1
>>> assert 0 < age < 100, 'The age must be realistic'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AssertionError: The age must be realistic
循环
while循环
使用下面的代码:
x = 1
while x <= 100:
print(x)
x += 1
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]
>>> range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
可以使用下面的代码打印1到100:
for i in range(1,101):
print(i)
xrange()函数的循环行为类似于range()函数,区别在于range()函数一次创建整个序列,而xrange一次只创建一个数。当需要迭代一个巨大的序列时xrange会更高效,不过一般情况下不需要过多关注它。
循环遍历字典
使用下面的代码:
d = {'x':1,'y':2,'z':3}
for key in d:
print(key+'corresponds to'+str(d[key]))
编号迭代
这一部分主要讲enumerate的用法。这一部分主要来自http://blog.csdn.net/churximi/article/details/51648388。
enumerate()说明
- enumerate()是Python的内置函数
- 对于一个可迭代/可遍历的对象,enumerate将其组成一个索引序列,利用它可以同时获得索引和值
- enumerate多用于在for循环中得到计数
enumerate()使用
对于一个列表,既要遍历索引又要遍历元素时,首先可以这样写:
list1 = ['这', '是', '一个', '测试']
for i in range(len(list1)):
print i,list1[i]
还可以用enumerate来实现
list1 = ['这', '是', '一个', '测试']
for index,item in enumerate(list1):
print index,item
如果要统计文件的行数,可以这样写:
count = len(open(filepath, 'r').readlines())
这种方法简单,但是可能比较慢,当文件比较大时甚至不能工作。
可以利用enumerate():
count = -1
for index, line in enumerate(open(filepath,'r')):
count += 1
翻转和迭代排序
使用下面的代码:
>>> sorted('Hello, world!')
[' ', '!', ',', 'H', 'd', 'e', 'l', 'l', 'l', 'o', 'o', 'r', 'w']
>>> list(reversed('Hello, world!'))
['!', 'd', 'l', 'r', 'o', 'w', ' ', ',', 'o', 'l', 'l', 'e', 'H']
>>> ''.join(reversed('Hello, world!'))
'!dlrow ,olleH'
跳出循环
- break
- continue
- while True break
循环中的else子句
当在循环内使用break语句是,通常是因为“找到”了某物或者因为某事“发生”了。在跳出时做一些事情是很简单的,但是有时候想要在没有跳出之前做些事情。
可以使用布尔变量,在循环前将其设定为False,跳出后设定为True,然后再使用if语句查看循环是否跳出了。伪代码如下:
broke_out = False
for x in seq:
dosomething(x)
if condition(x):
broke_out = True
break
do_something_else(x)
if not broke_out:
print ("I didn't break out")
更简单的方式是在循环中增加一个else子句——它仅在没有调用break时执行。
from math import sqrt
for n in range(99,81,-1):
root = sqrt(n)
if root == int(root):
print n
break
else:
print "Didn't find it"
列表推导式——轻量级循环
列表推导式是利用其它列表创建新列表的一种方法。它的工作方式类似于for循环。
使用下面的代码:
>>> [x*x for x in range(10)]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> [x*x for x in range(10) if x % 3 == 0]
[0, 9, 36, 81]
>>> [(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)]
三人行
pass
表示一个方法为空。
def fun():
pass
del
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']
>>> del x
>>> y
['Hello', 'Python']
x和y都指向一个对象,但是删除x不会影响y,因为这删除的只是x这个名字,而不是列表本身。Python中是没有办法删除值的。这些工作由Python解释器负责。
使用exec和eval执行和求值字符串
有些时候会需要动态的创造Python代码,然后将其作为语句执行或作为表达式计算。在此之前一定要慎之又慎,仔细考虑。
使用下面的的代码:
>>> exec "print 'Hello world!'"
Hello world!
有些时候也会出现问题:
>>> from math import sqrt
>>> exec "sqrt = 1"
>>> sqrt(4)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not callable
exec语句最有用的地方在于可以动态的创建代码字符串。如果字符串是从其他地方获得的——用户那儿——那么几乎不能确定其中到底包含什么代码。为了安全起见,可以增加一个字典,起到命名空间的作用。
使用下面的代码:
>>> from math import sqrt
>>> scope = {}
>>> exec "sqrt=1" in scope
>>> sqrt(4)
2.0
>>> scope['sqrt']
1
eval用于求值,是类似于exec的内建函数。exec会执行Python语句,而eval会计算Python表达式,并返回结果值。
使用下面的代码:
>>> eval(raw_input("Enter an arithmetic expression:"))
Enter an arithmetic expression:(1+2)*(3+4)
21