提到zip,各位小伙伴想到了啥?是不是压缩包文件呢?
zip()是Python的内建函数,这个函数可能比较抽象,刚开始学习的时候不知道如何使用,学习这个函数更多的是需要了解使用的思想。
zip()函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。
语法
zip([iterable, ...])
参数:
- iterable -- 一个或多个迭代器,如列表等等
返回:元组列表
用法
a = [1,2,3]
b = [4,5,6]
c = [4,5,6,7,8]
z = zip(a,b)
print(z)
# 返回的是一个对象。
# <zip object at 0x000001C4CE93A508>
# 可以用list()将这个对象转换为列表
a = list(z)
print(a)
# [(1, 4), (2, 5), (3, 6)]
print(list(zip(a,c)))
# [(1, 4), (2, 5), (3, 6)] #不能够成对的部分将被舍弃
特殊用法:
zip(*)这个函数也被称为zip()的逆函数,但是我个人认为这个叫法似乎不那么好理解。*这个符号在这里发挥的不是一个乘法的作用,他更像是将*号后面的可迭代对象进行了拆解,然后再传入zip()函数。我们以下面的例子说明:
a = [[1,2,3],[4,5,6]]
print(list(zip(a)))
# [([1, 2, 3],), ([4, 5, 6],)]
# 我们发现这个结果并不是我们想要的,他将a里面的每个list视为一个整体。而我们预期的结果应该是
# [[1,4],[2,5],[3,6]]
print(list(zip(a[0],a[1])))
# [(1, 4), (2, 5), (3, 6)]
# 这就得到了我们想要的结果,而zip(*)所作的事情就是这样,将list in list里面的list进行拆解,传入
print(list(zip(*a)))
# [(1, 4), (2, 5), (3, 6)]
# 与上面的结果一致
通过上面的例子,可以看到,当list in list中有很多List的时候,采取zip(*)可以简化我们的代码。
例子
这里,我们以leetcode的一道题【2500】为例。
如果依照题目的步骤,可以写出如下代码:思路就是重复遍历list in list,每次取出list中的最大值,并移除他,暂时保存在一的列表d中,最后取d中的最大值相加,直到两个列表为空。
class Solution:
def deleteGreatestValue(self, grid: List[List[int]]) -> int:
ans = 0
while grid:
d = []
for i in grid:
if not i: #如果为空,则跳过
continue
else:
d.append(max(i)) #将最大的添加到d中,暂时保存
i.remove(max(i)) #从列表中移除最大的值
if d:
ans = ans + max(d) #每次循环从d中取最大的相加
else:
break
return ans
如果换个思路,不需要对列表进行这么复杂的操作,如下图:
官方题解代码:
class Solution:
def deleteGreatestValue(self, grid: List[List[int]]) -> int:
for i in grid:
i.sort()
return sum([max(i) for i in zip(*grid)])
可以看到,代码简洁了不少,避免了大量的循环,提高了运行的效率,相较于原版本有了较大的提升。
总结
zip()函数的使用频率不是特别高,在学习的过程中要注重使用的思路,合理的运用,简化代码,提高运行效率。