《Python基础教程》学习笔记 Chap5 条件、循环和其他语句

1.print和import的更多信息

使用逗号输出

print可以打印多个表达式,只要将多个表达式用逗号分开就好,输出的时候每个表达式之间都会插入一个空格,这种方式并不会构成一个元组。例:

>>> print 'age', 42, 'name', 'alice'
age 42 name alice


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

可以在语句末尾增加一个as子句,在该子句后给出想要使用的别名,可以为整个模块提供别名,也可以为某个函数提供别名。例:

>>> import math as foobar
>>> foobar.sqrt(2)
1.4142135623730951
>>> from math import sqrt as foobar
>>> foobar(2)
1.4142135623730951


2.赋值魔法

序列解包

多个赋值操作同时进行,或者交换两个(或者更多个)变量也是可以的。例:

>>> x, y, z = 1,2,3
>>> print x, y, z
1 2 3
>>> x,y = y,x
>>> print x, y
2 1
>>> values = 1,2,3
>>> values
(1, 2, 3)
>>> x,y,z = values
>>> print x, y, z
1 2 3

上述例子所做的事情就是序列解包或递归解包,将多个值的序列解开,然后放到变量的序列中。当函数或者方法返回元组(或者其他序列或可迭代对象时),这个特性尤为重要,它允许函数返回一个以上的值并且打包成元组,然后通过一个赋值语句很容易进行访问。例:

>>> d = {'url': 'http://www.python.org', 'changed': 'Mar 14 22:09:05 MET 2015', 'title': 'Python language website'}
>>> key, value  = d.popitem()
>>> key
'url'
>>> value
'http://www.python.org'

注:所解包的序列中的元素数量必须和放置在赋值符号=左边的变量的数量完全一致,否则会在赋值时引发异常。

>>>  x, y, z = 1,2
Traceback (  File "<interactive input>", line 1
    x, y, z = 1,2
    ^
IndentationError: unexpected indent
>>>  x, y, z = 1,2,3,4
Traceback (  File "<interactive input>", line 1
    x, y, z = 1,2,3,4
    ^
IndentationError: unexpected indent

Python3.0中有另外一种解包特性:可以像在函数的参数列表中一样使用星号运算符。例如:a,b,*rest = [1,2,3,4,5,6]最终会在a,b都被赋值之后将所有其他的参数都收集到rest中。


链式赋值

链式赋值是将一同一个值赋给多个变量的捷径。例:

>>> x = y  = 4

和下面语句的效果是一样的:
>>> x = 4
>>> x = y

但是上面的语句和下面的语句不一定等价:
>>> x = 4
>>> y = 4


增量赋值

对于*、/、%或者其他数据类型(只要二元运算符本身适用于这些数据类型即可)。例:
>>> str = 'hello'
>>> str += ' world'
>>> str
'hello world'


3.条件和条件语句

这就是布尔变量的作用

下面的值在作为布尔表达式的视乎,会被解释其看做假(false),换句话说,也就是标准值False、None、所有类型的数字0(包括浮点型、长整型、和其他类型)、空序列(比如空字符串、元组和列表)以及空的字典都是假,其他的一切都被解释为真,包括特殊值True。

False     None      0      “”      ()       []        {}

也就是说,Python中的所有值都能被解释为真值。“标准的”布尔值为True和False,与1he0的作用是相同的。例:

>>> True
True
>>> False
False
>>> True + False
1
>>> True == 1
True
>>> False == 0
True

布尔值Ture和False属于布尔类型,bool函数可以用来转换其他值。

>>> bool('I am learning Python')
True
>>> bool(4)
True
>>> bool("")
False
>>> bool(0)
False

条件执行和if语句

>>> name = raw_input('my name is :')
>>> name
'putty'
>>> if name.endswith('putty'):print 'hello , putty'
... 
hello , putty

else子句

>>> name = raw_input('my name is :')
>>> name
'fjao'
>>> if name.endswith('putty'):
... print 'hello , putty'
... else:
... print 'hello!'
...
hello!

elif

如果检查多个条件,就可以使用elif,是if else的简写。

>>> num = input('input a number :')
>>> num
3
>>> if num > 0 :
... print 'positive number !'
... elif num < 0 :
... print 'negative number !'
... else :
... print 'zero !'
...
positive number !


4.更复杂的条件

相等运算符

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

is:同一性运算符

>>> x = y =[1,2]
>>> z = [1,2]
>>> x == y
True
>>> x is y
True
>>> x == z
True
>>> x is z
False
>>> x is not z
True

注:使用==运算符来判定两个对象是否相等,使用is判定两者是否是同一个对象。

布尔运算符

and运算符就是所谓的布尔运算符。它连接两个布尔值,并且在两者都为真时返回真,否则返回家。与它同类的还有两个运算符,or和not。and和or都是短路逻辑,同java中的&&和||。

>>> num = input('enter a number between 1 and 10')
>>> num
5
>>> if num <= 10 and num >= 1:
... print 'Great !'
... else :
... print 'Wrong !'
...
Great !

断言

有时候与其让程序晚些时候崩溃,不如在错误条件出现时就直接让它崩溃。一般来说,我们可以要求某些条件必须为真,语句中使用的关键字就是assert。例:

>>> age = 10
>>> assert 0 < age < 100
>>> age = -1
>>> assert 0 < age < 100
Traceback (most recent call last):
  File "<interactive input>", line 1, in <module>
AssertionError

如果需要确保程序中的某个条件为真才能让程序正常运行的话,assert语句就有用了,他可以在程序中置入检查点。条件后可以添加字符串,用来解释断言。例:

>>> age = -1
>>> assert 0 < age < 100, 'age must be realistic'
Traceback (most recent call last):
  File "<interactive input>", line 1, in <module>
AssertionError: age must be realistic

循环遍历字典元素

for循环中一大好处就是可以循环中使用序列解包。例:

>>> d = {'x' : 1, 'y' : 2, 'z' : 3}
>>> for key, value in d.items():
... print key, 'corresponds to ', value
...
y corresponds to  2
x corresponds to  1
z corresponds to  3


5.一些迭代工具

并行迭代

程序可以同时迭代两个序列,例如:

>>> names = ['anne', 'beth', 'george', 'damon']
>>> ages = [12, 45, 32, 102] 
>>> for i in range(len(names)): #这里i是循环索引的标准变量名
... print names[i], 'is', ages[i], 'year old .'
...
anne is 12 year old .
beth is 45 year old .
george is 32 year old .
damon is 102 year old .

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

>>> names = ['anne', 'beth', 'george', 'damon']
>>> ages = [12, 45, 32, 102] 
>>> zip(names, ages)
[('anne', 12), ('beth', 45), ('george', 32), ('damon', 102)]

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

>>> for name, age in zip(names, ages) : 
... print name,  'is', age, 'year old .'
...
anne is 12 year old .
beth is 45 year old .
george is 32 year old .
damon is 102 year old .

zip函数也可以作用于任意多的序列。关于它很重要的一点是zip可以处理不等长的序列,当最短的序列“用完”的时候就会停止。例:

>>> zip(range(5), xrange(100000000))
[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)]

在上面的代码中,不推荐用range替换xrange----尽管只需要前面5个数字,但range会计算所有的数字,这要话费很长的时间。而使用xrange就没有这个问题了,它只计算前5个数字。

按索引迭代

for index, string in enumerate(strings):

if 'xxx' in strng:

strings[index] = ['cencored']

如上述函数所示,内建的enumerate函数可以在提供索引的地方迭代索引-值对。

>>> strings = ['hello', 'world', 'ni', 'hao']
>>> for index, string in enumerate(strings):
... if 'ni' in string :
... print index
...
2

翻转和排序迭代

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

>>> a = [4,5,7,2,1,9,14,8]
>>> sorted(a)
[1, 2, 4, 5, 7, 8, 9, 14]
>>> a
[4, 5, 7, 2, 1, 9, 14, 8]
>>> b = 'hello , world'
>>> sorted(b)
[' ', ' ', ',', 'd', 'e', 'h', 'l', 'l', 'l', 'o', 'o', 'r', 'w']
>>> list(reversed(b))
['d', 'l', 'r', 'o', 'w', ' ', ',', ' ', 'o', 'l', 'l', 'e', 'h']
>>> ''.join(reversed(b))
'dlrow , olleh'
>>> b
'hello , world'

列表推导式

书写形式:[expr for value in collection ifcondition]

过滤条件可有可无,取决于实际应用,只留下表达式;相当于下面这段for循环:

  1. result = []  
  2. for value in collection:  
  3.     if condition:  
  4.         result.append(expression)  

更详细的介绍可以参考以下博客:http://blog.csdn.net/jerry_1126/article/details/42044245

>>> [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(10) for y in range(10)]
[(0, 0), (0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (0, 6), (0, 7), (0, 8), (0, 9), (1, 0), (1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (1, 7), (1, 8), (1, 9), (2, 0), (2, 1), (2, 2), (2, 3), (2, 4), (2, 5), (2, 6), (2, 7), (2, 8), (2, 9), (3, 0), (3, 1), (3, 2), (3, 3), (3, 4), (3, 5), (3, 6), (3, 7), (3, 8), (3, 9), (4, 0), (4, 1), (4, 2), (4, 3), (4, 4), (4, 5), (4, 6), (4, 7), (4, 8), (4, 9), (5, 0), (5, 1), (5, 2), (5, 3), (5, 4), (5, 5), (5, 6), (5, 7), (5, 8), (5, 9), (6, 0), (6, 1), (6, 2), (6, 3), (6, 4), (6, 5), (6, 6), (6, 7), (6, 8), (6, 9), (7, 0), (7, 1), (7, 2), (7, 3), (7, 4), (7, 5), (7, 6), (7, 7), (7, 8), (7, 9), (8, 0), (8, 1), (8, 2), (8, 3), (8, 4), (8, 5), (8, 6), (8, 7), (8, 8), (8, 9), (9, 0), (9, 1), (9, 2), (9, 3), (9, 4), (9, 5), (9, 6), (9, 7), (9, 8), (9, 9)]


6.三人行

pass

有的时候,程序什么事情都不用做,这种情况下可以使用pass语句。例:

>>> pass
>>> name = raw_input('enter name : ')
>>> name
'dfa'
>>> if name == 'Alice' :
... print 'Hello , Alice'
... elif name == 'Boby' :
... print 'Hello , Boby'
... else :
... pass
... 

del

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

>>> x = 1
>>> del x
>>> x
Traceback (most recent call last):
  File "<interactive input>", line 1, in <module>
NameError: name 'x' is not defined

看起来很简单,但有时理解起来有些难度。例:

>>> x = y = [1,2,3,4]
>>> y[1] = 5
>>> x
[1, 5, 3, 4]
>>> y
[1, 5, 3, 4]
>>> del x
>>> x
Traceback (most recent call last):
  File "<interactive input>", line 1, in <module>
NameError: name 'x' is not defined
>>> y
[1, 5, 3, 4]

原因分析:x和y都指向同一个列表,但是删除x并不会影响y,原因就是删除的只是名称,而不是列表本身(值)。事实上,在Python中是没有办法删除值的(因为某个值不再使用的时候,Python解释器会负责内存的回收)。

使用exec和eval执行和求值字符串

exec

执行一个字符串的语句是exec,在python3.0中,exec是函数而不是语句。例:

>>> exec "print 'hello , world !'"
hello , world !

使用简单形式的exec的语句不是好事,很多情况下可以给它提供命名空间(或称为作用域),从而是代码不会干扰命名空间(也就是不会改变你的变量)。例:

>>> from math import sqrt
>>> exec "sqrt = 1"
>>> sqrt(2)
Traceback (most recent call last):
  File "<interactive input>", line 1, in <module>
TypeError: 'int' object is not callable

所以为了安全起见,可以增加一个字典,起到命名空间的作用。例:

>>> from math import sqrt
>>> scope = {}
>>> exec "sqrt = 1" in scope
>>> sqrt(4)
2.0
>>> scope['sqrt']
1

可以看到,潜在的破坏性代码并不会覆盖sqrt函数,原来的函数能正常工作,而通过exec赋值的变量sqrt只在它的作用域内有效。

注意:如果需要将scope打印出来的话,会看到其中包含很多东西,因为内建的_builtins_字典会自动包含所有的内建函数和值。例:

>>> len(scope)
2
>>> scope.keys()
['__builtins__', 'sqrt']

eval

eval(用于“求值”)是类似于exec的内建函数。exec语句会执行一系列Python语句,而eval会计算python表达式(以字符串形式书写),并且返回结果值。(exec语句并不会返回任何对象,因为它本身就是语句。)例:

>>> eval(raw_input('enter an expression : '))
enter an expression : 5 + 48 * 3
149

注:表达式eval(raw_input(...))事实上等同于input,在python3.0中,raw_input被重命名为input。


7.新函数

chr(n) 当传入序号n时,返回n所代表的包含一个字符的字符串(0<=n<256)

eval(source[, globals[, locals]]) 将字符串作为表达式计算,并且返回值

enumerate(seq) 产生用于迭代的(索引,值)对

ord(c) 返回单字符字符串的int值

range([start,] stop[, step]) 创建整数的列表

reversed(seq)   产生seq中值的反向版本,用于迭代

sorted(seq[, cmp][, key][, reverse])   返回seq中值排序后的列表

xrange([start,] stop[, step] 创造xrange对象用于迭代

zip(seq1,seq2,..... 创造用于并行迭代的新序列

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值