一、zip的简单介绍:
zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的对象,这样做的好处是节约了不少的内存。
我们可以使用 list() 转换来输出列表。
如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同,利用 * 号操作符,可以将元组解压为列表。
二、简单使用场景介绍:
这个内置模块我还是看到一个别人写的博客中用到这个模块,然后不太明白,就搜了下简单使用,不过感觉还不错,对于爬虫提取数据的时候,确实有用,下面我举几个我以后工作中会用到的小例子:
1、循环一个列表(获取对应的下表和值):
如果是之前,我会使用循环的时候,然后使用一个变量num作为一个递增当作下标。
1 | # 1、获取对应的列表 |
2 | # 我之前的用法 |
3 | list_demo1 = ['https://mp.csdn.net/mdeditor/102776886'+ str(i) for i in range(100000)] |
4 | start_time = time.time() |
5 | num = 0 |
6 | for i in list_demo1: |
7 | |
8 | print(num,i) |
9 | num += 1 |
10 | end_time = time.time() |
11 | print(end_time-start_time) |
12 | # 0.4557325839996338 |
使用zip,因为使用的range循环模拟真实场景,所以次数要多一点,不然时间间隔看不出来效果,效率差不多,不过我感觉zip返回的是个压缩,如果过大,我感觉直接遍历就行,不用使用list转化了。
1 | # 我使用zip的用法 |
2 | list_demo1 = ['https://mp.csdn.net/mdeditor/102776886' + str(i) for i in range(100000)] |
3 | start_time = time.time() |
4 | index_list = (i for i in range(len(list_demo1))) |
5 | for num, i in zip(index_list, list_demo1): |
6 | print(num, i) |
7 | end_time = time.time() |
8 | print(end_time - start_time) |
9 | # 0.42674970626831055 |
如果想要一个列表list,里面是元组,也可以使用enumerate内置模块,自动配置下标,就是比zip上面的方法稍微满一点,不过这个如果只是需要下标,这个内存最简单。
1 | # # 我使用zip的用法 |
2 | list_demo1 = ['https://mp.csdn.net/mdeditor/102776886' + str(i) for i in range(100000)] |
3 | start_time = time.time() |
4 | |
5 | result = enumerate(list_demo1) |
6 | for i in result: |
7 | print(i) |
8 | end_time = time.time() |
9 | print(end_time - start_time) |
10 | # 0.627619743347168 |
2、循环俩个列表(这种我代码中用的比较多):
需求:俩个list,需要对应的下标位置的元素,需要拼接成一个元素,比如以爬取的一次IP和端口号为例吧:
1 | re_ip_address = ['115.231.5.230', '114.239.147.135', '123.163.97.18', '223.243.255.167', '121.232.148.178', |
2 | '121.233.109.15', '114.239.250.93', '58.23.230.24', '220.168.52.245', '183.166.102.92', |
3 | '219.159.38.209', '47.100.21.174', '163.204.245.172', '118.180.166.195', '182.35.86.221'] |
4 | re_port = ['44524', '9999', '9999', '65309', '9000', '9999', '9999', '8118', '39107', '9999', '56210', '8021', '9999', |
5 | '8060', '9999'] |
6 | |
7 | for ip, port in zip(re_ip_address, re_port): |
8 | print(ip + ':' + port) |
打印的就是这种的。这种方法很方便,不然循环提取一个html中的a标签的text和href,之前我都是提取a标签,比如,现在就可以使用xpath提取一个a标签的list和href的list,然后使用这个,我感觉效率肯定比之前一个一个遍历再提取快的多。如果这种有时候一个项目提取次数要达到几百万甚至上千万,效率和节省的时间就体现出来了。
下面写下我之前用的方法:
1 | # 用下标方法,循环俩个list |
2 | re_ip_address = ['115.231.5.230', '114.239.147.135', '123.163.97.18', '223.243.255.167', '121.232.148.178', |
3 | '121.233.109.15', '114.239.250.93', '58.23.230.24', '220.168.52.245', '183.166.102.92', |
4 | '219.159.38.209', '47.100.21.174', '163.204.245.172', '118.180.166.195', '182.35.86.221'] |
5 | re_port = ['44524', '9999', '9999', '65309', '9000', '9999', '9999', '8118', '39107', '9999', '56210', '8021', '9999', |
6 | '8060', '9999'] |
7 | |
8 | for i in range(len(re_ip_address)): |
9 | ip = re_ip_address[i] |
10 | port = re_port[i] |
11 | ip_one = ip + ":" + port |
12 | print('ip_one', ip_one) |
3、zip(*)解压
这个功能只是把之前的zip压缩的列表,返回成元组tuple类型返回,我自我感觉目前没有什么用,需要我直接tuple换就行了。
1 | re_ip_address = ['115.231.5.230', '114.239.147.135'] |
2 | re_port = ['44524', '9999'] |
3 | |
4 | result1 = zip(re_ip_address, re_port) |
5 | result2 = zip(* result1) |
6 | print('result2',result2) |
7 | print('result2',list(result2)) |
直接tuple我感觉更简单:
1 | |
2 | re_ip_address = ['115.231.5.230', '114.239.147.135'] |
3 | re_port = ['44524', '9999'] |
4 | result = [tuple(re_ip_address),tuple(re_port)] |
5 | print('result2', result) |