解包和打包的对象是可迭代对象:
解包
模拟解包过程
def unpack_example(iterable):
it = iter(iterable) # 获取迭代器
a = next(it) # 获取第一个元素
b = next(it) # 获取第二个元素
c = list(it) # 获取剩余的所有元素
return a, b, c
result = unpack_example([1, 2, 3, 4, 5])
print(result) # 输出: (1, 2, [3, 4, 5])
直接解包
a, b, c = [1, 2, 3]
*捕获剩余元素
a, *_, c = [1, 2, 3, 4]
循环中的解包
pairs = [(1, 'one'), (2, 'two'), (3, 'three')]
for num, word in pairs:
print(num, word)
打包
zip 函数将多个可迭代对象作为参数,返回一个元组iterator,每个元组包含来自所有输入可迭代对象的相应元素。(注意:每一个iterator都需要实现__iter__()函数,所以每一个iterator都是一个iterable,所以这里的zip之后的结果虽然是iterator,但仍然可以使用for loop来访问。)
a = [1, 2, 3]
b = ['one', 'two', 'three']
c = [4.0, 5.0, 6.0]
print(zip(a, b, c))
print(*zip(a, b, c))
# <zip object at 0x106ff1140>
# (1, 'one', 4.0) (2, 'two', 5.0) (3, 'three', 6.0)
这里*zip(a, b, c)的返回结果是对iterator解包,iterator中的每个元素都会被取出,直到iterator耗尽。
zip等价函数
def zip(*iterables):
iterators = [iter(it) for it in iterables]
while iterators:
result = []
for it in iterators:
try:
result.append(next(it))
except StopIteration:
return
yield tuple(result)
这里函数的参数是*iterables,这表明会将接受对象整合为一个元组。
我们传入的参数也是一系列的对象,可以通过对iterator解包来实现这一点。
l = range(5)
zip(*l)
iterable
iterable是一个形容词,描述实现了__iter__方法的对象,使用__iter__方法可以得到一个iterator。
每一个生成器,也就是generator object,都是iterable
x = (i for i in range(3))
# x=<generator object <genexpr> at 0x1065dec20>