Python zip()函数笔记

本文介绍了Python内置函数zip()的用法,通过示例解析如何利用zip()结合sorted()解决一对一对应的数组排序问题。内容包括zip()的语法、返回值特性和常见操作,以及zip()在处理不同长度迭代器时的行为。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

引子

最近在刷题时碰到一个排序的子问题,问题大致是有两个整型数组a和b,a和b的元素是一一对应的,现需要以a为基准排序,且a和b的对应关系不能变。
假设有数组 a = [ 100 , 700 , 300 , 150 , 450 ] a = [100, 700, 300, 150, 450] a=[100,700,300,150,450] b = [ 1 , 2 , 3 , 4 , 5 ] b = [1, 2, 3, 4, 5] b=[1,2,3,4,5],根据上述题目要求,排序后应当有 a = [ 100 , 150 , 300 , 450 , 700 ] a = [100, 150, 300, 450, 700] a=[100,150,300,450,700] b = [ 1 , 4 , 3 , 5 , 2 ] b = [1, 4, 3, 5, 2] b=[1,4,3,5,2]。这个问题可以很方便的用Python的内置函数zip()和sorted()进行解决,代码如下所示:

a = [100, 700, 300, 150, 450]
b = [1, 2, 3, 4, 5]
z1, z2 = zip(*sorted(zip(a, b)))
z1 = list(z1)
z2 = list(z2)
print('a =', z1, '\nb =', z2)

输出为:

a = [100, 150, 300, 450, 700] 
b = [1, 4, 3, 5, 2]

说明

zip()函数用于将可迭代的对象(列表、元组、字典)作为参数,将对象中对应的元素打包成一个个元素,然后返回由这些元素组成的对象(Python 3中返回对象,Python 2中返回列表),这样做的好处是节约了不少的内存。
我们可以使用list()转换来输出列表。

语法

zip语法:

zip([iterable, …])

其中iterable表示一个或多个可迭代对象,在Python里可以是列表、元组、字典。
返回值是一个迭代器对象。

示例

看下面这段代码:

a = [1, 2, 3]
b = [4, 5, 6]

print(zip(a, b))
print(list(zip(a, b)))

输出为:

<zip object at 0x0000015C93E522C8>
[(1, 4), (2, 5), (3, 6)]

zip()函数返回的是可迭代对象,我们想要直接获取它的返回值,一般是将其转换为list或者tuple,而它们内部每个元素都是tuple形式的。
对于返回的list或tuple其内部每个元素都是tuple形式,我们还可以参考下面的例子:

a = [[1, 2], [3, 4]]
b = [[5, 6], [7, 8]]

z = list(zip(a, b))
print(z)

此时的输出为:

[([1, 2], [5, 6]), ([3, 4], [7, 8])]

当在循环中使用zip()函数时,实际上是使用的zip对象的__next__()方法。
比如我们可以这样用:

for z1, z2 in zip(a, b):
    print(z1, z2)

输出就为:

1 4
2 5
3 6

或者我们可以直接调用__next__()方法:

z = zip(a, b)
for i in range(len(a)):
    print(z.__next__())

这样输出就为:

(1, 4)
(2, 5)
(3, 6)

由于zip()函数返回的是迭代器对象,所以我们不能反复的使用返回值,比如像下面这样:

z = zip(a, b)
print(list(z))
for z1, z2 in z:
    print(z1, z2)

这时的输出是:

[(1, 4), (2, 5), (3, 6)]

可以看到for循环中无法再次获取值了。其实,这个问题也是可以解决的,只要将返回的对象转换成list或者tuple保存到新的变量就可以了,如下所示:

z = list(zip(a, b))
print(z)
for z1, z2 in z:
    print(z1, z2)

这时的输出是:

[(1, 4), (2, 5), (3, 6)]
1 4
2 5
3 6

另外,如果zip()函数输入的各个迭代器的元素个数不一致,则返回的列表与最短长度的对象相同,比如:

a = [1, 2, 3]
b = [4, 5, 6, 7, 8]

z = list(zip(a, b))
print(z)

输出为:

[(1, 4), (2, 5), (3, 6)]

最后,利用*操作符,也就是zip(*)函数可以将元组解压为列表,比如:

c = [['A', 'a'], ('B', 'b'), ('C', 'c')]
print(list(zip(*c)))

输出为:

[('A', 'B', 'C'), ('a', 'b', 'c')]

也就是说上面的c可以看做('A', 'B', 'C')('a','b', 'c')压缩而成,解压后自然就得到他们两个了。
现在,对于引子里面的例子我想你应该看明白了。首先我们调用zip()函数将a和b打包成元组,然后再使用sorted()函数对其进行排序。由于排序的每个元素是一个由a和b中的对应元素组成的元组,而元组排序时默认以第一个成员为基准进行排序(也就是a中的元素),排序好之后再使用zip(*)函数对其解压,那么就得到了以a中元素为基准排序且b中元素与之一一对应的两个元组了。最后再将其转换成列表就是我们所要的了(根据实际需要也可以不转换,a和b现在都是元组类型,也是可迭代的)。
如果文章中有什么问题,欢迎读者朋友们在评论区指出,我会及时纠正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值