Python中zip()和map()的使用

0 前言

在一段用matplotlib绘制三维轨迹图的代码中,用到了zip()和map(),现将其使用方法记录一下。

1 zip() 函数

1.1 描述

zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。

如果各个迭代器的元素个数不一致,则返回列表的长度与最短的对象相同,利用 * 号操作符,可以将元组解压为列表。

zip 方法在 Python 2 和 Python 3 中的不同:在 Python 3.x 中为了减少内存,zip() 返回的是一个对象。如需展示列表,需手动 list() 转换。
如果需要了解 Pyhton3 的应用,可以参考 Python3 zip()

1.2 语法

zip() 语法:

zip([iterable, ...])

参数说明:

  • iterable:一个或多个迭代器

1.3 返回值

返回由元组组成的列表。

1.4 实例

(1)Python 2

>>> a = [1,2,3]
>>> b = [4,5,6]
>>> c = [4,5,6,7,8]
>>> zipped = zip(a,b)     # 打包为元组的列表
[(1, 4), (2, 5), (3, 6)]
>>> zip(a,c)              # 元素个数与最短的列表一致
[(1, 4), (2, 5), (3, 6)]
>>> zip(*zipped)          # 与 zip 相反,*zipped 可理解为解压,返回二维矩阵式
[(1, 2, 3), (4, 5, 6)]

(2)Python 3

>>>a = [1,2,3]
>>> b = [4,5,6]
>>> c = [4,5,6,7,8]
>>> zipped = zip(a,b)           # 返回一个对象
>>> zipped
<zip object at 0x103abc288>
>>> list(zipped)                # list() 转换为列表
[(1, 4), (2, 5), (3, 6)]
>>> list(zip(a,c))              # 元素个数与最短的列表一致
[(1, 4), (2, 5), (3, 6)]
>>> a1, a2 = zip(*zip(a,b))     # 与 zip 相反,zip(*) 可理解为解压,返回二维矩阵式
>>> list(a1)
[1, 2, 3]
>>> list(a2)
[4, 5, 6]

1.5 补充

列表元素一次相连:

# -*- coding: UTF-8 -*-

l = ['a', 'b', 'c', 'd', 'e','f']
print l

#打印列表
print zip(l[:-1],l[1:])

输出结果:

['a', 'b', 'c', 'd', 'e', 'f']
[('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'e'), ('e', 'f')]
nums = ['flower','flow','flight']
for i in zip(*nums):
    print(i)

输出结果:

('f', 'f', 'f')
('l', 'l', 'l')
('o', 'o', 'i')
('w', 'w', 'g')

2 map() 函数

2.1 描述

map() 会根据提供的函数对指定序列做映射。

第一个参数 function 以参数序列中的每一个元素调用 function 函数,返回包含每次 function 函数返回值的新列表。

2.2 语法

map() 函数语法:

map(function, iterable, ...)

2.3 参数

  • function:函数
  • iterable:一个或多个序列

2.4 返回值

Python 2.x 返回列表。

Python 3.x 返回迭代器。

2.5 实例

>>>def square(x) :            # 计算平方数
...     return x ** 2
... 
>>> map(square, [1,2,3,4,5])   # 计算列表各个元素的平方
[1, 4, 9, 16, 25]
>>> map(lambda x: x ** 2, [1, 2, 3, 4, 5])  # 使用 lambda 匿名函数
[1, 4, 9, 16, 25]
 
# 提供了两个列表,对相同位置的列表数据进行相加
>>> map(lambda x, y: x + y, [1, 3, 5, 7, 9], [2, 4, 6, 8, 10])
[3, 7, 11, 15, 19]

2.6 补充

(1)如果函数有多个参数, 但每个参数的序列元素数量不一样, 会根据最少元素的序列进行。

>>> listx = [1,2,3,4,5,6,7]       # 7 个元素
>>> listy = [2,3,4,5,6,7]         # 6 个元素 
>>> listz = [100,100,100,100]     # 4 个元素
>>> list_result = map(lambda x,y,z : x**2 + y + z,listx, listy, listz)
>>> print(list(list_result))
[103, 107, 113, 121]

明显可以看出,由于 lambda 中的 z 参数实际是使用了 listz, 而 listz 里面只有 4 个元素,所以即使 listx 有 7 个元素,listy 有 6 个元素,也不会继续执行了,只执行了 4 个元素的的计算。

(2)除了计算幂函数,还可利用 map 函数的映射功能完成其他任务,例如规范名字格式。

#!/usr/bin/python
# -*- coding: UTF-8 -*-

name_list={'tony','cHarLIE','rachAEl'}
def format_name(s):
    ss=s[0:1].upper()+s[1:].lower();
    return ss;
print (list(map(format_name,name_list)))

type(name_list)

程序将字符串的首字母大写,其余字母小写。

(3)filter 是通过生成 True 和 False 组成的迭代器,将可迭代对象中不符合条件的元素过滤掉;而 map 返回的则是 True 和 False 组成的迭代器。

>>> res1 = map(lambda n: n > 5, range(10))
>>> lt1 = list(res1)
>>> print(lt1)
[False, False, False, False, False, False, True, True, True, True]

>>> res2 = filter(lambda n: n > 5, range(10))
>>> lt = list(res2)
>>> print(lt) 
[6, 7, 8, 9]

(4)python 中二维数组的转置

如果 zip(*array) 不经过 x,y,z=zip(*array); 拆分成 x,y,z 三个变量,那么 [[1,4,7],[2,5,8],[3,6,9]]; 被 zip(*array) 之后的结果恰好是 [(1, 2, 3), (4, 5, 6), (7, 8, 9)],刚好形成一个转置的关系。这对于所有 array=[[1,2,3],[4,5,6],[7,8,9]]; 的二维数组都是一样的。

在这里插入图片描述
当然 [(1, 2, 3), (4, 5, 6), (7, 8, 9)] 还不是我们需要的最后的结果。

因为只是一个存放 tuple 的 list,我们要保持原来 list 是存 list 的一致性,所以要应用到上方的 map 函数。

因此对于一个数组的转置,代码如下:

>>> array = [[1, 4], [2, 5], [3, 6]];
>>> map(list, zip(*array));
[[1, 2, 3], [4, 5, 6]]

另一个实例:

>>> list(zip([1, 3, 5, 7, 9], [2, 4, 6, 8, 10]))
[(1, 2), (3, 4), (5, 6), (7, 8), (9, 10)]
>>> list(map(lambda x,y : [x,y], [1,3,5,7,9], [2,4,6,8,10]))
[[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]]

3 matplotlib绘图

# -*- coding: utf-8 -*-
"""
Created on Thu Jun 22 21:43:55 2017

@author: hyj
"""

import numpy as np
import matplotlib
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

import os
filepath=os.path.abspath('..')+"/bin"  #表示当前所处的文件夹上一级文件夹的绝对路径

position = []
tx_index = 5

with open(filepath + '/imu_pose.txt', 'r') as f:  # imu_circle   imu_spline

    data = f.readlines()  # txt中所有字符串读入data
    for line in data:
        odom = line.split()  # 将单个数据分隔开存好
        numbers_float = map(float, odom)  # 转化为浮点数

        position.append([numbers_float[tx_index], numbers_float[tx_index + 1], numbers_float[tx_index + 2]])

position1 = []

with open(filepath + '/imu_int_pose.txt', 'r') as f:  # imu_pose   imu_spline

    data = f.readlines()  # txt中所有字符串读入data
    for line in data:
        odom = line.split()  # 将单个数据分隔开存好
        numbers_float = map(float, odom)  # 转化为浮点数

        position1.append([numbers_float[tx_index], numbers_float[tx_index + 1], numbers_float[tx_index + 2]])
        
### plot 3d
fig = plt.figure()
ax = fig.gca(projection='3d')

xyz = zip(*position)
xyz1 = zip(*position1)
print
ax.plot(xyz[0], xyz[1], xyz[2], label='gt')
ax.plot(xyz1[0], xyz1[1], xyz1[2], label='imu_int')
ax.legend()

ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
plt.show()

解析:

  • map(float, odom)odom转化为浮点数
  • zip(*position)position中的x,y,z分别放在一起

4 参考

[1] https://www.runoob.com/python/python-func-map.html
[2] https://www.runoob.com/python/python-func-zip.html
[3] 《视觉SLAM进阶:从零开始手写VIO》第二讲作业代码

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值