上QQ阅读APP看书,第一时间看更新
3.5 序列解包的多种形式和用法
序列解包(Sequence Unpacking)是Python中非常重要和常用的一个功能,可以使用非常简洁的形式完成复杂的功能,提高了代码的可读性,减少了程序员的代码输入量。
>>>x, y, z=1,2,3 #多个变量同时赋值 >>>v_tuple=(False,3.5, 'exp') >>>(x, y, z)=v_tuple >>>x, y, z=v_tuple >>>x, y, z=range(3) #可以对range对象进行序列解包 >>>x, y, z=iter([1,2,3]) #使用迭代器对象进行序列解包 >>>x, y, z=map(str, range(3)) #使用可迭代的map对象进行序列解包 >>>a, b=b, a #交换两个变量的值
序列解包还可以用于列表、字典、enumerate对象、filter对象、zip对象等。对字典使用时,默认是对字典“键”进行操作,如果对“键:值”对进行操作应使用字典的items()方法说明,如果需要对字典“值”进行操作应使用字典的values()方法明确指定。
>>>a=[1,2,3] >>>b, c, d=a #列表也支持序列解包的用法 >>>x, y, z=sorted([1,3,2]) #sorted()函数返回排序后的列表 >>>s={'a':1, 'b':2, 'c':3} >>>b, c, d=s.items() #这里的重点是序列解包的用法 >>>b ('c',3) >>>b, c, d=s #使用字典时不用太多考虑元素的顺序 >>>b #在Python 3.6.x和更新版本中略有不同是正常的 'c' >>>b, c, d=s.values() >>>print(b, c, d) 1 3 2 >>>a, b, c='ABC' #字符串也支持序列解包 >>>print(a, b, c) A B C
使用序列解包可以很方便地同时遍历多个序列。
>>>keys=['a', 'b', 'c', 'd'] >>>values=[1,2,3,4] >>>for k, v in zip(keys, values): print((k, v), end='') ('a',1) ('b',2) ('c',3) ('d',4) >>>x=['a', 'b', 'c'] >>>for i, v in enumerate(x): print('The value on position{0}is{1}'.format(i, v)) The value on position 0 is a The value on position 1 is b The value on position 2 is c >>>s={'a':1, 'b':2, 'c':3} >>>for k, v in s.items(): #字典中每个元素包含“键”和“值”两部分 print((k, v), end='') ('a',1) ('b',2) ('c',3)
下面的代码演示了序列解包的另类用法和错误的用法:
>>>print(*[1,2,3],4, *(5,6)) 1 2 3 4 5 6 >>>*range(4),4 (0,1,2,3,4) >>>*range(4) #不允许这样用 SyntaxError: can't use starred expression here >>>{*range(4),4, *(5,6,7)} {0,1,2,3,4,5,6,7} >>>{'x': 1, **{'y': 2}} {'y': 2, 'x': 1} >>>a, b, c=range(3) >>>a, b, c=*range(3) #不允许这样用 SyntaxError: can't use starred expression here >>>a, b, c, d=*range(3),3
下面的代码看起来与序列解包类似,但严格来说是序列解包的逆运算,与函数的可变长度参数一样(详见5.2.4节),用来收集等号右侧的多个数值。
>>>a, *b, c=1,2,3,4,5 >>>a, b, c (1, [2,3,4],5) >>>b [2,3,4] >>>a, *b, c=1,2,3,4 >>>a, b, c (1, [2,3],4) >>>a, *b, c=tuple(range(20)) >>>b [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18] >>>*b=1,2,3,4 #等号左侧必须为列表、元组或多个变量 SyntaxError: starred assignment target must be in a list or tuple