Python zip, unzip, zip_longest的用法

目录

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.5501icon-default.png?t=L892https://blog.csdn.net/chenxy_bwave/article/details/120110095?spm=1001.2014.3001.5501

  • 9
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

笨牛慢耕

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值