目录
0. 前言
1. zip()有什么好处?
2. zip基本使用方法
2.1 语法
2.2 使用例
3. 反向操作:unzip
4. zip_longest()
0. 前言
本文简单介绍python中的zip()方法的使用,并相应介绍与之相关联的itertools模块中的zip_longest()。
简而言之,Python中的zip()方法是用于提高并行迭代(parallel iteration)的效率的。
1. 基本的iterable遍历方法
常规的遍历一个iterables的基本做法有以下两种:
weekdays = ['Monday','Wendsday','Tuesday','Thursday','Friday','Saturday','Sunday']
for wd in weekdays:print(wd,end=', ')
print('\n')
for k in range(len(weekdays)):print(weekdays[k],end=', ')
print('\n')
当我们有两个或者多个长度相等的iterables,需要遍历并每次从各iterables中取一个元素(序号对应)进行处理呢?我们可以这样做:
weekdays = ['Monday','Wendsday','Tuesday','Thursday','Friday','Saturday','Sunday']
weekdays_chinese = ['星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期日' ]
for k in range(len(weekdays)):print(weekdays[k],' --> ', weekdays_chinese[k])
但是,这种方法只在多个iterables的长度相同时才能行得通。如果不一定相等的话,就需要提前进行比较并选取其中最小的长度作为遍历范围,否则的话就可能出错。比如说,
weekdays = ['Monday','Wendsday','Tuesday','Thursday','Friday','Saturday','Sunday']
weekdays_chinese = ['星期一', '星期二', '星期三', '星期四', '星期五', '星期六' ]
min_len = min(len(weekdays),len(weekdays_chinese))
for k in range(min_len):print(weekdays[k],' --> ', weekdays_chinese[k])
如果,需要进行并行迭代处理的各iterables的长度在程序运行过程中还会动态发生变化的话,情况就更加复杂了。
2. zip基本使用方法
zip()方法提供了很方便的进行并行迭代的工具。
2.1 语法
Syntax : zip(*iterators)
Parameters : Python iterables or containers ( list, string etc )
Return Value : Returns a single iterator object, having mapped values from all the containers.
根据python docs, zip()用于创建将多个iterables中的元素聚合起来使用的迭代器(iterator).
1. 返回一个元组的迭代器(iterator of tuples), 第i个元组包含各输入iterables的第i个元素.
2. 迭代器在最短的输入iterable用完时停止 -- 因此不必担心各iterable长度不同时会报错
3. 如果输入只有一个iterable参数的话, 它就返回以1-tuple为元素的迭代器.
4. 如果没有指定参数的话,返回的是空的迭代器
2.2 使用例
例1:
weekdays = ['Monday','Wendsday','Tuesday','Thursday','Friday','Saturday','Sunday']
weekdays_chinese = ['星期一', '星期二', '星期三', '星期四', '星期五', '星期六' ]
zipPair = zip(weekdays, weekdays_chinese)
print(zipPair)
print(list(zipPair))
输出:
<zip object at 0x000001C7896A55C0>
[('Monday', '星期一'), ('Wendsday', '星期二'), ('Tuesday', '星期三'), ('Thursday', '星期四'), ('Friday', '星期五'), ('Saturday', '星期六')]
注意,在这个例子中,两个输入列表的长度是不相同,zip()进行了判断并按照较短的那个进行处理。
zip()返回的是一个zip对象,第一条print()打印的结果是它的指针信息。第二条print()将它映射为列表再打印出来。
例2:多个iterables输入
weekdays = ['Monday','Wendsday','Tuesday','Thursday','Friday','Saturday','Sunday']
weekdays_chinese = ['星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期日' ]
weekdays_japanese = ['月曜日', '火曜日', '水曜日', '木曜日', '金曜日', '土曜日','日曜日' ]
zipTriple = zip(weekdays, weekdays_chinese, weekdays_japanese)
print(list(zipTriple))
输出:[('Monday', '星期一', '月曜日'), ('Wendsday', '星期二', '火曜日'), ('Tuesday', '星期三', '水曜日'), ('Thursday', '星期四', '木曜日'), ('Friday', '星期五', '金曜日'), ('Saturday', '星期六', '土曜日'), ('Sunday', '星期日', '日曜日')]
例3:如果zip()的输入参数只有一个iterables或者甚至没有呢?好吧,谁闲的慌会这么做呢?
a = [1,2,3,4,5]
print(list(zip(a)))
print(list(zip()))
[(1,), (2,), (3,), (4,), (5,)]
[]
3. 反向操作:unzip
既然可以将多个iterables中的元素聚合到一起来使用,那能不能将它们分解开来呢?太能了!用zip(*zip_object)的方式将一个由zip()生成的zip object传递给zip(),注意前面要加一个"*"号,就可以实现将zip object又还原成各个iterables了。
zipTriple = zip(weekdays, weekdays_chinese, weekdays_japanese)
wk1, wk2, wk3 = zip(*zipTriple)
print(wk1)
print(wk2)
print(wk3)
输出:
('Monday', 'Wendsday', 'Tuesday', 'Thursday', 'Friday', 'Saturday', 'Sunday')
('星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期日')
('月曜日', '火曜日', '水曜日', '木曜日', '金曜日', '土曜日', '日曜日')
4. zip_longest()
前面说到当多个输入iterables的长度不相等的时候,zip会按照最小的长度进行迭代处理。但是,如果需要按照最长的那个进行迭代处理,那怎么办呢?
有办法,在itertools模块中提供了一个叫做zip_longest()的方法,就是用于弥补zip()这一短板的。如下例所示:
import itertools as it
fruits = ['apple', 'banana', 'melon', 'strawberry']
prices = [10, 20, 30]
print(list(it.zip_longest(fruits, prices)))
输出:[('apple', 10), ('banana', 20), ('melon', 30), ('strawberry', None)]
由于prices中少了一项,python缺省地补了个None跟fruits中的最后一项配对。
当然你可以加上你想要的配对项,比如:
fruits = ['apple', 'banana', 'melon', 'strawberry']
prices = [10, 20, 30]
print(list(it.zip_longest(fruits, prices, fillvalue='Sold out')))
输出:[('apple', 10), ('banana', 20), ('melon', 30), ('strawberry', 'Sold out')]
通过zip_longest()的可选项输入参数“fillvalue”指定了在长度不足时的配对项“Sold Out”。当然在这个例子中,这个指定的配对项只适合于prices列表较短的情况。
Hope you enjoy this blog!
关于itertools模块如果想知道得更多,还可以参阅:python itertools详解及使用示例https://blog.csdn.net/chenxy_bwave/article/details/120110095?spm=1001.2014.3001.5501https://blog.csdn.net/chenxy_bwave/article/details/120110095?spm=1001.2014.3001.5501