序列赋值
从技术的角度来讲,序列赋值语句实际上支持右侧任何可迭代的对象,而不仅局限于任何序列。
虽然可以在“=”符号两侧混合相匹配的序列类型,右边元素的数目还是要跟左边的变量的数目相同,不然会产生错误。
>>> a = 1
>>> b = 2
>>> A,B = a,b
>>> A,B
(1, 2)
>>> A
1
>>> [C,D]=A,B
>>> C,D
(1, 2)
>>> [C,D]=[A,B]
>>> C,D
(1, 2)
>>> [C,D]=[1,2,3]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: too many values to unpack (expected 2)
>>> [C,D]=(1,2)
>>> C,D
(1, 2)
>>> [C,D]='as'
>>> C,D
('a', 's')
高级赋值语句模式
>>> a,b,c = string[0],string[1],string[2:]
>>> a,b,c
('S', 'P', 'AM')
>>> a,b,c = list(string[:2])+string[2:]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only concatenate list (not "str") to list
>>> a,b,c = list(string[:2])+[string[2:]]
>>> a,b,c
('S', 'P', 'AM')
>>> a,b = string[:2]
>>> c=string[2:]
>>> a,b,c
('S', 'P', 'AM')
>>>
>>> (a,b),c = string[:2],string[2:]
>>> a,b,c
('S', 'P', 'AM')
L = [1,2,3,4]
while L:
front,L = L[0],L[1:]
print(front,L)
'''结果如下:
1 [2, 3, 4]
2 [3, 4]
3 [4]
4 []
'''
扩展的解包的实际应用
在目标中使用带单个星号的名称来更通用地匹配。
>>> seq = [1,2,3,4]
>>> a,b,c,d = seq
>>> print(a,b,c,d)
1 2 3 4
>>> a,b = seq
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: too many values to unpack (expected 2)
>>> a,*b = seq
>>> a
1
>>> b
[2, 3, 4]
>>>
>>> *a,b = seq
>>> a
[1, 2, 3]
>>> b
4
>>>
>>> a,*b,c = seq
>>> a
1
>>> b
[2, 3]
>>> c
4
>>>
>>> a,b,*c = seq
>>> a
1
>>> b
2
>>> c
[3, 4]
>>>
>>> a,*b = 'spam'
>>> a
's'
>>> b
['p', 'a', 'm']
>>>
>>> a,*b,c = seq
>>> a
1
>>> b
[2, 3]
>>> c
4
>>>
>>> L = [1,2,3,4]
>>> while L:
... fornt,*L = L
... print(fornt,L)
...
1 [2, 3, 4]
2 [3, 4]
3 [4]
4 []
边界情况
如果没有剩下的内容可以匹配带星号的名称,它会赋值一个空的列表,不管该名称出现在哪里。最后,如果有多个带星号的名称,或者如果值少了而没有带星号的名称,以及如果带星号的名称自身没有编写到一个列表中,都将会引发错误。
>>> seq
[1, 2, 3, 4]
>>> a,b,c,*d = seq
>>> print(a,b,c,d)
1 2 3 [4]
>>> a,b,c,d,*e = seq
>>> print(a,b,c,d,e)
1 2 3 4 []
>>>
>>> a,*b,c,*d = seq
File "<stdin>", line 1
SyntaxError: two starred expressions in assignment
>>>
>>> a,b = seq
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: too many values to unpack (expected 2)
>>>
>>> *a = seq
File "<stdin>", line 1
SyntaxError: starred assignment target must be in a list or tuple
>>>
>>> *a, = seq
>>> a
[1, 2, 3, 4]
应用于for循环
>>> for (a,*b,c) in [(1,2,3,4),(4,5,6,7)]:
... print(a,b,c)
...
1 [2, 3] 4
4 [5, 6] 7
多目标赋值语句
这里只有一个对象,三个变量共享(全都指向内存内同一对象)。这种行为对于不可变类型而言并没问题。只要赋值的对象是不可变的,即使有一个以上的变量名使用该对象也无所谓,不过,就像往常一样,把变量初始值设为空的可变对象时(诸如列表或字典),我们就得小心一点。为避免这种问题,要在单独的语句中初始化可变对象,一边分别执行独立的常量表达式来创建独立的空对象。
>>> a = b = c = 'apam'
>>> a,b,c
('apam', 'apam', 'apam')
>>>
>>> c = 'ok'
>>> a,b,c
('apam', 'apam', 'ok')
>>> a = b = 0
>>> b = b + 1
>>> a,b
(0, 1)
>>>
>>> a = b = []
>>> b.append(42)
>>> a,b
([42], [42])
>>>
>>> a = []
>>> b = []
>>> b.append(42)
>>> a,b
([], [42])
>>>
增强赋值语句
>>> x = 1
>>> x = x + 1
>>> x
2
>>> x += 1
>>> x
3
>>>
>>> S = 'spam'
>>> S += 'spam'
>>> S
'spamspam'
增强赋值语句三个优点:
程序员输入减少;左侧只需要计算一次,执行速度更快;优化技术会自动选择。
>>> L=[1,2]
>>> M=L
>>> L=L+[3,4]
>>> L,M
([1, 2, 3, 4], [1, 2])
>>>
>>> L=[1,2]
>>> M=L
>>> L+=[3,4]
>>> L,M
([1, 2, 3, 4], [1, 2, 3, 4])
"+="隐含着对列表做原处修改的意思。于是,完全不像“+”合并,总是生成新对象。
变量命名规则
Python中区分大小写,包括创建的变量名以及保留字。
Python3.0版本中的保留字:
False class finally is return
None continue for lambda try
True def from nonlocal while
and del global not with
as elif if or yield
assert else import pass
break except in raise
表达式语句
虽然表达式在Python中可作为语句出现,但语句不能用作表达式。例如,Python不让你把赋值语句(=)嵌入到其他表达式中。这样做的理由是为了避免常见的编码错误。
表达式语句通常用于执行可于原处修改列表的列表方法。
>>> x = print('spam')
spam
>>> print(x)
None
>>>
>>> L = [1,2]
>>> L.append(3)
>>> L
[1, 2, 3]
>>> L=L.append(4)
>>> print(L)
None
打印操作
Python3.0的print函数的应用
>>> print() # Display a blank line
>>> x = 'spam'
>>> y = 99
>>> z = ['eggs']
>>> print(x,y,z)
spam 99 ['eggs']
>>> print(x,y,z,sep='')
spam99['eggs']
>>> print(x,y,z,end='')
spam 99 ['eggs']>>>
>>>
>>> print(x,y,z,end='');print(x,y,z)
spam 99 ['eggs']spam 99 ['eggs']
>>> print(x,y,z,end='...\n')
spam 99 ['eggs']...
>>> print(x,y,z,sep='...',end='!\n')
spam...99...['eggs']!
>>> print(x,y,z,sep='...',file=open('data.txt','w')) # print to a file
>>> print(x,y,z)
spam 99 ['eggs']
>>> print(open('data.txt').read())
spam...99...['eggs']
>>> text = '%s: %-.4f, %05d'%('Result',3.14159,42)
>>> print(text)
Result: 3.1416, 00042
打印流重定向
>>> print('hello world')
hello world
>>> 'hello world'
'hello world'
>>>
>>>
>>> import sys
>>> sys.stdout.write('hello world\n')
hello world
12
>>> import sys
>>> temp = sys.stdout
>>> sys.stdout = open('log.txt','a')
>>> print('spam')
>>> print(1,2,3)
>>> sys.stdout.close()
>>> sys.stdout = temp
>>>
>>> print('back here')
back here
>>> print(open('log.txt').read())
spam
1 2 3
>>> log1 = open('log1.txt','w')
>>> print(1,2,3,file=log1)
>>> print(4,5,6,file=log1)
>>> log1.close()
>>> print(open('log1.txt').read())
1 2 3
4 5 6
>>> import sys
>>> sys.stderr.write(('Bad!'*8)+'\n')
Bad!Bad!Bad!Bad!Bad!Bad!Bad!Bad!
33
>>> print('Bad!'*8,file=sys.stderr)
Bad!Bad!Bad!Bad!Bad!Bad!Bad!Bad!
>>> X=1;Y=2
>>> print(X,Y)
1 2
>>> import sys
>>> sys.stdout.write(str(X)+' '+str(Y)+'\n')
1 2
4
>>> print(X,Y,file=open('temp1','w'))
>>> open('temp2','w').write(str(X)+' '+str(Y)+'\n')
4
>>> print(open('temp1','rb').read())
b'1 2\r\n'
>>> print(open('temp2','rb').read())
b'1 2\r\n'
版本独立的打印
from __future__ import print_function
该语句可以把Python2.6修改为支持Python3.0的print函数。通过这种方法,我们可以使用Python3.0 print功能。
字符串格式化表达式:
>>>print('%s %s %s' %('spam','ham','eggs'))
spam ham eggs
>>> print('{0} {1} {2}'.format('spam','ham','eggs'))
spam ham eggs