你们好,我又回来了,今天我想和你们分享的是Python很是重要的几个内置函数:map,filter,reduce, zip。主要用处在于处理序列(Sequence)。咱们能够利用它们把一些小函数应用于一个序列的全部元素。从而节省编写显式循环的时间。python
另外,map,filter,reduce, zip都是纯函数,有返回值。所以咱们能够容易地将函数的返回结果用表达式来表示。数组
我我的的理解是使用它们,能够简化咱们的代码,从而更简洁高效地执行一些须要用到循环迭代的任务,接下来是一些具体例子bash
函数构造app
map()函数的主要做用是能够把一个方法依次执行在一个可迭代的序列上,好比List等,具体的信息以下:函数
其实就是利用map映射,咱们能够把一个函数fun 执行到序列iterable的每个元素上,用例子很是好理解~学习
基础用法:测试
下面先让咱们看一个小例子,假设如今咱们有一个List,包含1~5五个数字,咱们想要让每个数+1,若是不知道map这个函数以前,咱们的解决方案是这样的:优化
numbers = [1, 2, 3, 4, 5]
for i in range(0,len(numbers)): #对每一个元素加1
numbers[i]+=1
print(numbers)
Out:[2, 3, 4, 5, 6]
复制代码
或者是这样的:ui
numbers = [1, 2, 3, 4, 5]
result = []
for n in numbers:
result.append(n+1)
print(result)
Out:[2, 3, 4, 5, 6]
复制代码
这里用列表表达式会更好,我会在以后的文章总结spa
可是显然,不管怎么作都会涉及到写循环,这里就是map函数的用武之地了,咱们能够用map函数这样实现:
def add_one(n):
return n + 1
numbers = [1, 2, 3, 4, 5]
result = map(add_one, numbers)
print(result)
print(type(result))
print(list(result))
Out:<map object at 0x00000260F508BE80>
<class 'map'>
[2, 3, 4, 5, 6]
复制代码
这里咱们发现了map的好处,在精简代码的同时,某种程度上实现了方法和循环部分的分离,这里咱们发现map返回就是map类,咱们这里传递的序列是List,最后输出时通过类型转换也是list
在传递序列时只要这个序列是可迭代的就好,不必定非要List,好比咱们换一种:
def add_one(n):
return n + 1
numbers = (1, 2, 3, 4, 5) #序列为元组
result = map(add_one, numbers)
print(tuple(result)) #
Out:(2, 3, 4, 5, 6)
复制代码
输入的序列为一样能够迭代的元组,输出时咱们也选择元组,效果同样的。
如今优化一下,还用刚才的例子,为了更简洁,咱们用lambda函数配合map使用:
numbers = (1, 2, 3, 4, 5) # 迭代对象为tuple
result = map(lambda x: x + 1, numbers)
print(list(result)) # 输出对象为list
Out:[2, 3, 4, 5, 6]
复制代码
更加简洁优雅了对吧!!这个lambda函数我以后会说,今天它不是主角,先一带而过。让咱们从新把目光转移到map上来,除了刚才的用法,还要一种状况也十分常见,像以下这个例子:
# List of strings
words = ['paris', 'xiaobai','love']
# 把数组中每一个元素变为List
test = list(map(list, words))
print(test)
Out: [['p', 'a', 'r', 'i', 's'], ['x', 'i', 'a', 'o', 'b', 'a', 'i'], ['l', 'o', 'v', 'e']]
复制代码
words是一个只包含字符串类型元素的list,咱们用map能够实现将words的每个元素所有转化为list类型,这里有一点必定要注意,能实现的前提必定是每一个元素都是能够迭代的类型,若是出现了如int类型的元素,就会出错啦:
# List of strings
words = [18,'paris', 'xiaobai','love']
# 把数组中每一个元素变为List
test = list(map(list, words))
print(test)
Out:TypeError: 'int' object is not iterable
复制代码
你们一看错误类型相比马上就明白了,因此正确的使用方法必定是相似这种:
nums = [3,"23",-2]
print(list(map(float,nums)))
Out: [3.0, 23.0, -2.0]
复制代码
总之就是类型要注意,我仅仅是抛砖引玉简单介绍一下map,具体的用法你们能够自行开发哈,我也在不断学习中
函数构造
filter()方法借助于一个函数来过滤给定的序列,该函数测试序列中的每一个元素是否为真。
简而言之就是filter能够帮助咱们根据给出的条件过滤一组数据并返回结果
基础用法:
让咱们先看一个例子:
# 过滤元音的方法
def fun(variable):
letters = ['a', 'e', 'i', 'o', 'u']
if (variable in letters):
return True
else:
return False
# 给定序列
sequence = ['I', 'l', 'o', 'v', 'e', 'p', 'y','t','h','o','n']
# 根据条件得出结果
filtered = list(filter(fun, sequence))
print(filtered)
Out:['o', 'e', 'o']
复制代码
这里咱们建立一个能够提取元音字母的方法fun,给定的可迭代序列为list,以后就能够用filter方法很容易的提取出结果啦,再看一个相似例子:
# 判断为正数
def positive(num):
if num>0:
return True
else:
return False
#判断偶数
def even(num):
if num % 2==0:
return True
else:
return False
numbers=[1,-3,5,-20,0,9,12]
positive_nums = list(filter(positive, numbers))
print(positive_nums) # 输出正数 list
even_nums = tuple(filter(even,numbers))
print(even_nums) #输出偶数 tuple
Out:[1, 5, 9, 12]
(-20, 0, 12)
复制代码
看到这里相比你们已经知道filter的基础用法, 要先有一个能返回True或者False的方法,或者表达式做为过滤条件就好了
更进一步
这里其实和map同样了,基本上最简洁的用法都是和lambda混在一块儿,好比下面咱们想要把刚才的一大串代码压缩一下:
numbers = [0, 1, 2, -3, 5, -8, 13]
# 提取奇数
result = filter(lambda x: x % 2, numbers)
print("Odd Numbers are :",list(result))
# 提取偶数
result = filter(lambda x: x % 2 == 0, numbers)
print("Even Numbers are :",list(result))
#提取正数
result = filter(lambda x: x>0, numbers)
print("Positive Numbers are :",list(result))
Out:Odd Numbers are : [1, -3, 5, 13]
Even Numbers are : [0, 2, -8]
Positive Numbers are : [1, 2, 5, 13]
复制代码
" 爽啊!爽死了!" 郭德纲看到后这么评价,lambda我平时用的很少,可是这里使用正好能够体现python的理念之一:高效简洁!
函数构造
Reduce是一个很是有用的函数,用于在列表上执行某些计算并返回结果。它将滚动计算应用于列表中的连续值。例如,若是要计算整数列表的累积乘,或者求和等等
在Python 2中,reduce()是一个内置函数。可是,在Python 3中,它被移动到functools模块。所以,要使用前咱们须要导入,这里个人环境是Python 3.6
基础用法:
先看一个求累加和的小栗子:
from functools import reduce # Python 3
def do_sum(x1, x2):
return x1 + x2
print(reduce(do_sum, [1, 2, 3, 4]))
Out:10
复制代码
再看一个累积乘法的例子:
from functools import reduce # Python 3
def multiply(x, y):
return x*y
numbers = [1,2,3,4]
print(reduce(multiply, numbers))
Out:24
复制代码
更进一步:
仍是和lambda混搭,更加简洁:
from functools import reduce # Python 3
numbers = [1,2,3,4]
result_multiply = reduce((lambda x, y: x * y), numbers)
result_add = reduce((lambda x,y: x+y), numbers)
print(result_multiply)
print(result_add)
Out:24
10
复制代码
函数构造
zip()的目的是映射多个容器的类似索引,以便它们能够仅做为单个实体使用。
基础用法:
其实以前咱们在讲dict的建立方法时提到过它,这里重新回顾一下:
keys = ['name','age']
values = ['xiaobai',18]
my_dict = dict(zip(keys,values))
print(my_dict)
Out:{'name': 'xiaobai', 'age': 18}
复制代码
zip能够支持多个对象,好比下面的例子
name = [ "xiaobai", "john", "mike", "alpha" ]
age = [ 4, 1, 3, 2 ]
marks = [ 40, 50, 60, 70 ]
# using zip() to map values
mapped = list(zip(name, age, marks))
print ("The zipped result is : "mapped)
Out:The zipped result is : [('xiaobai', 4, 40), ('john', 1, 50), ('mike', 3, 60), ('alpha', 2, 70)]
复制代码
这里咱们能够很容易的的把name,age,marks这三个list里面相同index的值映射打包在一块儿
更进一步:
经过上面的例子,咱们发现能够很容易的以相似1对1的形式把不一样对象的同一索引位置的值打包起来,那若是是解包呢?也是相似的,就是多了一个 * 而已
names, ages, marks = zip(*mapped)
print ("The name list is : ",names)
print ("The age list is : ",ages)
print ("The marks list is : ",marks)
Out: The name list is : ('xiaobai', 'john', 'mike', 'alpha')
The age list is : (4, 1, 3, 2)
The marks list is : (40, 50, 60, 70)
复制代码
今天主要为你们介绍了map,filter,reduce,zip四个高效的python内置函数的用法,我也是刚刚接触,了解不够深刻,若是介绍的有错误或者歧义还请你们多多谅解和包容,若是有大神能够进一步补充说明必定要写个评论呀,让咱们一块儿进步。