Python zip zip_longest

参考内置函数——python 3.10 文档

一、zip 函数

help(zip)
Help on class zip in module builtins:

class zip(object)
 |  zip(*iterables) --> A zip object yielding tuples until an input is exhausted.
 |  
 |     >>> list(zip('abcdefg', range(3), range(4)))
 |     [('a', 0, 0), ('b', 1, 1), ('c', 2, 2)]
1、创建一个聚合了来自每个可迭代对象中的元素的迭代器,返回一个元组的迭代器。
2、其中的第 i 个元组包含来自每个参数序列或可迭代对象的第 i 个元素。
3、当所输入可迭代对象中最短的一个被耗尽时,迭代器将停止迭代。
4、当只有一个可迭代对象参数时,它将返回一个单元组的迭代器。
5、不带参数时,它将返回一个空迭代器。
a = [1,2,3]
print(list(zip(a)))  # 只有一个可迭代参数
# 输出:[(1,), (2,), (3,)]

a = [1,2,3]
b = [4,5,6]
print(list(zip(a,b)))  # 两个可迭代参数长度相同时
# 输出:[(1, 4), (2, 5), (3, 6)]

a = [1,2,3,4]
b = [5,6,7]
print(list(zip(a,b))) # 两个可迭代参数长度不同时,按最短的组合输出
# 输出:[(1, 5), (2, 6), (3, 7)]

a = [[1,2,3], [4,5,6]]
b = [[7,8,9], [10,11,12]]
print(list(zip(a,b)))
# 输出:[([1, 2, 3], [7, 8, 9]), ([4, 5, 6], [10, 11, 12])]

1、zip(args) 逆操作

result = zip(a, b)
origin = zip(*result)  # 前面加*号,事实上*号也是一个特殊的运算符,叫解包运算符

可以得到原来的 a 和 b。

*zip() 的用法

list1 = ["A", "B", "C", "D", "E"]  
list2 = ["a", "b", "c", "d", "e"] 
temp = zip(list1, list2)
a, b = zip(*temp)
print(a,b) #('A', 'B', 'C', 'D', 'E') ('a', 'b', 'c', 'd', 'e')
print(list(zip(*zip(list1, list2)))) 
l1, l2 = zip(*zip(list1,list2))
print(l1,"\t",l2) 

x = [5,6,7]
print(list(zip(* [x] * 3)))  #[(5, 5, 5), (6, 6, 6), (7, 7, 7)]
# zip(* [x] * 3) 等价于 zip(x, x, x)

2、同时遍历多个字典

在 Python 3.6+ 中,字典成为了一种有顺序的集合。利用这个特性和 zip,我们可以同时遍历多个字典:

>>> dict_one = {'name': 'John', 'last_name': 'Doe', 'job': 'Python Consultant'}
>>> dict_two = {'name': 'Jane', 'last_name': 'Doe', 'job': 'Community Manager'}
>>> for (k1, v1), (k2, v2) in zip(dict_one.items(), dict_two.items()):
...     print(k1, '->', v1)
...     print(k2, '->', v2)
...
name -> John
name -> Jane
last_name -> Doe
last_name -> Doe
job -> Python Consultant
job -> Community Manager

3、对多个元素同时进行排序

names = ['John', 'Amy', 'Jack']
scores = [98, 100, 85]  
data = list(zip(names, scores))
data.sort()
# [('Amy', 100), ('Jack', 85), ('John', 98)]

# 对分数进行排序
data2 = list(zip(scores, names))
data2.sort()
# [(85, 'Jack'), (98, 'John'), (100, 'Amy')]

4、将数据成对进行计算

假设你有这样一个表格:

一月

二月

三月

销售额

52,000.00

51,000.00

48,000.00

成本

46,800.00

45,900.00

43,200.00

利润 = 销售额 - 成本,求每月的利润:

total_sales = [52000.00, 51000.00, 48000.00]
prod_cost = [46800.00, 45900.00, 43200.00]
for sales, costs in zip(total_sales, prod_cost):
	profit = sales - costs
	print(f'Total profit: {profit}')

结果是:

Total profit: 5200.0
Total profit: 5100.0
Total profit: 4800.0

5、构建字典

将两个列表合并起来,得到一个姓名-分数的字典:

stu = dict(zip(names, scores))
# {'John': 98, 'Amy': 100, 'Jack': 85}

6、矩阵的点乘、相加和相减。

m = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
n = [[2, 2, 2], [3, 3, 3], [4, 4, 4]]
#矩阵点乘
mat_pointmul = [ x * y for a, b in zip(m, n) for x, y in zip(a, b)]
print(mat_pointmul) #[2, 4, 6, 12, 15, 18, 28, 32, 36]
#矩阵相加,相减同理
mat_sum = [ x + y for a, b in zip(m,n) for x, y in zip(a, b)]
print(mat_sum)  #[3, 4, 5, 7, 8, 9, 11, 12, 13]

7、字符串处理

14. 最长公共前缀

方法一:

class Solution:
    def longestCommonPrefix(self, strs: List[str]) -> str:
        if len(strs) == 0: return ""        
        x = strs[0]

        for i,c in enumerate(x):        
            for y in strs[1:]:
                if len(y) <= i or c != y[i]:
                   return x[:i]

        return x

方法二:zip

class Solution:
    def longestCommonPrefix(self, strs: List[str]) -> str:
        result = ""
        for temp in zip(*strs):
        	if len(set(temp)) != 1: return result
	        result += temp[0]
            
        return result

二、zip_longest 函数

zip_longest 与 zip 函数唯一不同的是如果两个可迭代参数长度不同时,按最长的输出,长度不足的用 fillvalue 进行代替,默认为 None。

help(zip_longest)
Help on class zip_longest in module itertools:

class zip_longest(builtins.object)
 |  zip_longest(iter1 [,iter2 [...]], [fillvalue=None]) --> zip_longest object

例:

from itertools import zip_longest

a = [1,2,3,4]
b = [5,6,7]
print(list(zip_longest(a,b)))
# 输出:[(1, 5), (2, 6), (3, 7), (4, None)]