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循环:
- result = []
- for value in collection:
- if condition:
- result.append(expression)
>>> [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,.....) 创造用于并行迭代的新序列