map、reduce、zip三个函数可以用在不同需求下的需要迭代或循环进行的功能中。
1、map()
- 语法:
map(function, iterable, ...)
map函数的参数是由function和一个或多个序列组成,map运行机制就是对序列部分使用function进行处理并返回结果。python2与python3中的map函数略有不同,python2返回的是列表,python3返回的是map结构。
python3环境运行代码:
def fun(x):
return x**2
list1 = [1,2,3,4,5]
list2 = map(fun,list1)
print(list2)
返回结果为:
<map object at 0x000000000277E9B0>
需要再用一次list才能得到可用的结果:print(list(list2))
得到结果:[1, 4, 9, 16, 25]
2、reduce()
在python3中,reduce不再是python的内置函数,需要通过functools模块调用
from functools import reduce
- 语法:
reduce(function, iterable[, initializer])
与map类似,第一个参数也是function,可以自定义def一个函数,也可以使用lamba这样的表达式。不同的是,它会对后续可迭代的部分(链表,元组等)中的每一个元素进行迭代。
简单来说,同样是对list进行操作,map是以list为单位对多个list进行function处理,而reduce会对一个list里的每个具体值执行function。
from functools import reduce
def fun(x,y):
return x+y
list1 = [1,2,3,4,5]
list2 = reduce(fun, list1)
print(list2)
输出结果:15
3、zip()与zip(*)
zip在python2和python3中也有不同的返回值,python2返回的是处理后的list,python3返回的是zip对象,和map一样,需要再加一层list进行展示。
- 语法
zip([iterable, ...])
- zip函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的对象。也就是完成了序列→元组的过程;
- zip(*)则是zip函数的反向操作,将打包好的数据解压回去。
list1 = [1,2,3]
list2 = [4,5,6]
zip1 = zip(list1,list2)
print(list(zip1))
输出结果为:
[(1, 4), (2, 5), (3, 6)]
这里需要注意当两个list长度不一致的时候,会以较短的list长度为准。
当使用zip(* )对其进行解压时
zip2 = zip(*zip1)
print(list(zip2))
得到结果:
[(1, 2, 3), (4, 5, 6)]
对比一下可以发现结构发生了一点变化,并不是完全的还原了,从列表的嵌套编程了列表与元组的嵌套。后面可以使用这个小特点完成列到行的转换。
zip可以用于生成pandas中的dataframe。zip和zip(*)一起用可以实现df的列到行的转换。
首先我们可以用zip来构造一个dataframe:
import pandas as pd
list1 = [1,2,3]
list2 = [4,5,6]
df = pd.DataFrame(list(zip(list1,list2)),columns=["A","B"])
生成的结果是这样的:
A B
0 1 4
1 2 5
2 3 6
然后我们可以利用zip(*)和zip()使其列转行:
df2 = pd.DataFrame(list(zip(*zip(list1,list2))))
输出结果:
0 1 2
0 1 2 3
1 4 5 6
zip(* )还可以处理嵌套列表:
list1 = [[i, j]for i in range(3) for j in range(5)]
df_temp = pd.DataFrame({"A": list(zip(*list1))[0], "B": list(zip(*list1))[1]})
print(df_temp)
生成结果如下:
A B
0 0 0
1 0 1
2 0 2
3 1 0
4 1 1
5 1 2
怎么说呢,其实行列互换可以使用df.T即可,这是最简单输出也最规范的转置操作。zip和zip(*)的操作很灵活,这里也是借助它的打包和解包的特性玩了个小技巧。感觉zip函数还是很好用的。