Python学习笔记_第五章:条件,循环和其他语句

Python3.0中,print不在是语句而是一个函数(功能基本不变)

赋值的魔法

>>> x, y, z = 1, 2, 3
>>> print x, y, z
1 2 3

多个赋值操作可以同时进行

>>> x, y = y, x
>>> print x, y, z
2 1 3

可以交换两个变量的值(更多变量也是没问题的)

>>> scoundrel = {'name' : 'Robin', 'girlfriend' : 'Marion'}
>>> key, value = scoundrel.popitem()
>>> key, value
('girlfriend', 'Marion')
>>> print key, value
girlfriend Marion

当函数或方法返回元祖时,这个特性尤为重要,popitem方法将键-值对作为元祖返回,那么这个元祖可以直接赋值到两个变量中。
这里做的事事实上是序列解包,或递归解包。
Python3.0中有另外一个解包特性,可以像在函数参数列表中那样使用星号运算符

>>> a, b, *c = [1, 2, 3, 4]
>>> a, b, c
(1, 2, [3, 4])
>>> *a, b, c = [1, 2, 3, 4]
>>> a, b, c
([1, 2], 3, 4)

链式赋值

>>> x = y = 1
>>> x, y
(1, 1)

增量赋值

>>> fnord = 'foo'
>>> fnord += '**'
>>> fnord
'foo**'
>>> fnord *= 2
>>> fnord
'foo**foo**'

条件和条件语句

False None 0 "" () [] {} 作为布尔表达式时会被解释器看成是假
换句话说,也就是标准值False和None、所有类型的数字0(包括浮点型、长整型和其他类型)、空序列(比如空字符串、元祖、列表)以及空的字典都为假,其他的一切内建型都是真,但是我们可以自己构建可以被解释为真或假的对象。
bool函数可以用来转换其他值。

>>> bool('I think, therefore I am')
True
>>> bool(42)
True
>>> bool(0)

但是,所有值都可以用作布尔值,几乎不用对他们进行显式转换

流程控制

if else elif

更复杂的条件

1.比较运算符
x == y、x < yx > y、x >= y、x <= y、x != y、x is y、x is not y、x in y、x not in y
比较不兼容类型
Python3.0以前的版本是可行的,但是不应该这么做,因为执行结果不一定,Python3.0以后版本中,比较不兼容类型是违法的。
比较对象的时候可以使用内建函数cmp
有些运算符特别值得关注,后面开始介绍
1.is与==的区别
is是判断同一性,==是判断相等性
应避免将is运算符用于比较类似数值和字符串这类不可变值,由于Python内部操作这类对象的方式的原因,使用is运算符的结果是不可预测的。
2.字符串和序列比较
按照字母顺序排列进行比较

>>> ord('c')
99
>>> chr(99)
'c'

字符是按照本身的顺序值排列的,ord函数、chr函数的作用如上
3.布尔运算符
and、or、not
事实上,所有值都可以解释为布尔值,所有的表达式也都返回布尔值
短路逻辑
短路逻辑可以用来实现c和java中所谓的三元运算符(条件运算符:如表达式:()? a : b)Python2.5中有一个内置的条件表达式:
a if c else c

断言

关键字:assert
语法:assert (条件表达式),‘description’

>>> age = -1
>>> assert 0 < age < 100, 'age must be a number that bigger than 0 smaller than 100'

Traceback (most recent call last):
  File "<pyshell#18>", line 1, in <module>
    assert 0 < age < 100, 'age must be a number that bigger than 0 smaller than 100'
AssertionError: age must be a number that bigger than 0 smaller than 100

for、while
如何防止输入为一个由空格组成的字符串
1.while not name or name.isspace()
提示重新输入name
2.while not name.strip()
提示重新输入name
如果能使用for循环,尽量不要使用while
xrange函数的循环行为类似于range函数,区别在于range函数一次创建整个序列,而xrange函数一次只创建一个数。当需要迭代一个巨大的序列时xrange会更高效,Python3.0中,range会转换为xrange风格的函数。

循环遍历字典元素

>>> 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

仅仅需要一个for循环即可

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

Python2.2之前,只能用keys等字典方法来获取键,不能直接迭代字典,如果需要值用values方法代替keys方法,items方法返回键值对组成的元祖,for循环可以直接对其解包。

一些迭代工具

Python的迭代工具有些位于itertools模块儿中,还有一些内建的函数
1.并行迭代
使用内建的zip函数可以实现并行迭代,它的作用是压缩两个队列,然后返回一个元祖的列表

>>> names = ['zhangsan', 'lisi', 'wangwu']
>>> ages = ['17', '18', '19']
>>> for name, age in zip(names, ages):
    print name, age 
zhangsan 17
lisi 18
wangwu 19

zip函数也可以作用于任意多的序列,并且,可以处理不等长的序列,当最短序列用完时就会停止。
2.按索引迭代
按索引迭代一种有效的方法是使用内建的enumerate函数

>>> for index, name in enumerate(names):
    print index, name   
0 zhangsan
1 lisi
2 wangwu

3.翻转和排序迭代
sorted方法:返回排序后的序列,非原地排序
reversed方法:返回翻转后的序列,非原地翻转
sorted方法返回列表,而reversed方法返回一个奇怪的迭代对象,反正不是列表,但是可以放心地在join方法和for循环中使用,不过不能对它使用索引、分片以及调用list方法。

跳出循环

break, continue

循环中的else字句

>>> from math import sqrt
>>> for n in range(99, 81, -1):
    root = sqrt(n)
    if root == int(root):
        print n
        break
else:
    print "don't find it"

    
don't find it

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

列表推导式是用其他列表创建新列表的一种方法

>>> a = [x * x for x in range(10)]
>>> a
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

一般用法

>>> a = [x * x for x in range(10) if x % 3 == 0]
>>> a
[0, 9, 36, 81]

复杂一点的

>>> [(x, y) for x in range(3) for y in range(5)]
[(0, 0), (0, 1), (0, 2), (0, 3), (0, 4), (1, 0), (1, 1), (1, 2), (1, 3), (1, 4), (2, 0), (2, 1), (2, 2), (2, 3), (2, 4)]

包含多个for
注意使用普通圆括号代替方括号不会产生元祖推导式。Python2.3以前的版本中只会得到错误。而在最近的版本中会产生一个生成器

>>> grils = ['xiaomei', 'meina', 'linyu']
>>> boys = ['xiaoming', 'meiquan', 'longdong']
>>> letterGirls = {}
>>> for gril in grils:
    letterGirls.setdefault(gril[0], []).append(gril)

    
>>> print([b + '+' + g for b in boys for g in letterGirls[b[0]]])
['xiaoming+xiaomei', 'meiquan+meina', 'longdong+linyu']

字典的一个相关应用,上例中男孩名字的首字母集合应是女孩名字首字母集合的一个子集

三人行

什么都没有发生

pass

使用del删除

del不仅会移除一个对象的引用,也会移除名字本身,当两个名字同时引用同一个对象时用del删除name1后仍然可以通过name2访问到对象,原因是删除的仅仅是名字本身,而被引用的对象是不会被删除的,事实上,Python中没有办法删除值。

用exec和eval执行 和 求和某字符串

tip:CGI脚本:web服务器运行时外部程序的规范,按CGI编写的程序可以扩展服务器的功能。
1.exec:执行一个字符串的语句是exec,在Python3.0中,exec是一个函数而不是一个语句

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

exec最大意义在于动态创建代码字符串来修改程序,但这样做很不安全,可以通过增加一个字典,起到命名空间的作用。
可以通过增加in <scope>来实现,其中<scope>是可以起到放置代码字符串字符空间作用的字典

>>> from math import sqrt
>>> scope = {}
>>> exec 'sqrt = 1' in scope
>>> sqrt(4)
2.0
>>> scope['sqrt']
1
>>> len(scope)
2
>>> scope.keys()
['__builtins__', 'sqrt']

这种方式创建的字典中会自动加入一个‘builtins’键,可以索引到所有的内建函数
2.eval:一个内建函数,eval会计算Python表达式,并返回结果

>>> exec '6 + 18 * 2'
>>> 6 + 18 * 2
42
>>> eval('6 + 18 * 2')
42

Python3.0中row_input()被重命名为input()
根exec一样,eval也可以使用命名空间,尽管表达式几乎不像语句那样为变量重新赋值。这里可以给eval提供全局和局部两个命名空间,全局命名空间必须是字典,局部命名空间可以是任意形式的映射。
表达式一般不给变量重新赋值,但是某些情况下的确可以(比如可以调用函数给全局变量重新赋值)。所以对于不安全的的代码eval并不比exec安全。目前Python中没有任何执行不可信任代码的方式。一个可选方案是使用Python的实现,比如Jython,以及用一些本地机制,比如Java的sandbox功能。
初探作用域
给exec或者eval语句提供命名空间时,还可以在真正使用命名空间前放置一些值进去:

>>> scope = {}
>>> scope['x'] = 2
>>> scope['y'] = 3
>>> len(scope)
2
>>> eval('x * y', scope)
6
>>> len(scope)
3

同理,exec或eval调用的作用域也能在另一个上使用

>>> scope = {}
>>> exec 'x = 2' in scope
>>> eval ('x * x', scope)
4
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值