Python函数式编程之map/filter/reduce/sorted

关于函数式编程

  • 函数式编程Functional Programming,其思想更接近数学计算
  • 函数式编程就是一种抽象程度很高的编程范式,纯粹的函数式编程语言编写的函数没有变量,因此,任意一个函数,只要输入是确定的,输出就是确定的。
  • Python对函数式编程提供部分支持
  • 由于Python允许使用变量,因此,Python不是纯函数式编程语言
  • 函数式编程的一个特点就是,允许把函数本身作为参数传入另一个函数,还允许返回一个函数(你会想到,闭包?装饰器?)

map 映射

定义

  • 关键是声明和注释,内置方法你可以先忽略

    • map(func, *iterables) --> map object # 第一个参数是个函数名,第二个参数是个可迭代的对象
    • map的作用是将func作用到迭代器中的每个元素上
  1. class map(object)
  2. | map(func, *iterables) --> map object
  3. |
  4. | Make an iterator that computes the function using arguments from
  5. | each of the iterables. Stops when the shortest iterable is exhausted.
  6. |
  7. | Methods defined here:
  8. |
  9. | __getattribute__(self, name, /)
  10. | Return getattr(self, name).
  11. |
  12. | __iter__(self, /)
  13. | Implement iter(self).
  14. |
  15. | __next__(self, /)
  16. | Implement next(self).
  17. |
  18. | __reduce__(...)
  19. | Return state information for pickling.
  20. |
  21. | ----------------------------------------------------------------------
  22. | Static methods defined here:
  23. |
  24. | __new__(*args, **kwargs) from builtins.type
  25. | Create and return a new object. See help(type) for accurate signature.

实例

从简->难

1. 将列表中每个整数变为平方

  1. list1 = [1,2,3] # --> [1,4,9]
  2. # 循环
  3. list2 = []
  4. for _ in list1:
  5. list2.append(_**2)
  6. # 列表推导式
  7. [i**2 for i in list1]
  8. # map
  9. list(map(lambda x:x**2,list1))
  10. # 等价于
  11. def f(x):
  12. return x * x
  13. list(map(f,list1))
  • 从上面你可以看出来,map可以跟列表推导式一定程度上等价,当然也是可以用for来完成的。
  • map很多的时候跟lambda结合使用。
  • 效果见下图,map映射,有一一对应之意,将这个func(函数)作用到迭代器的每个元素上。

下面都是一些简单的例子而已

2. 将列表中每个整数变为字符串

  1. list1 = [1,2,3]
  2. list(map(str,list1))
  • 注意map返回的是map object

3. 得到学生姓名的列表

  1. students = [
  2. {"name": "John Doe",
  3. "father name": "Robert Doe",
  4. "Address": "123 Hall street"
  5. },
  6. {
  7. "name": "Rahul Garg",
  8. "father name": "Kamal Garg",
  9. "Address": "3-Upper-Street corner"
  10. },
  11. {
  12. "name": "Angela Steven",
  13. "father name": "Jabob steven",
  14. "Address": "Unknown"
  15. }
  16. ]
  • 像例子1-2是烂大街的map举例的,像3这种就不太明显了,但却非常适合用map

    1. list(map(lambda stu:stu['name'],students))
  • 当然还有一个问题是这样的lambda你是否能想到?(虽然比较简单)

4. 将2个列表中对应的数据相乘

  1. list1 = [1,2,3]
  2. list2 = [4,5,6] # -> [4,10,18] 1*4 2*5 3*6
  • 这个用列表推导式可以吗?反正我不太会做

    1. [i*j for i in list1 for j in list2] # [4, 5, 6, 8, 10, 12, 12, 15, 18] # 可以看到是一个双重for循环
  • 用map实现

    1. list(map(lambda x,y:x*y,list1,list2)) # 你可以看到x来自list1,y来自list2
    • 是的,map后面第一个参数是函数名,第二个参数是可迭代对象,但可以是多个。

5. 映射多个函数的一个示例

  1. # ×2
  2. def double(x):
  3. return x + x
  4. # 平方
  5. def square(x):
  6. return x * x
  7. # 数据
  8. list1 = [1, 2, 3 ]
  9. # 处理
  10. for i in list1:
  11. temp = tuple(map(lambda x: x(i), (double, square)))
  12. print(temp)
  13. ###
  14. # (2, 1)
  15. # (4, 4)
  16. # (6, 9)

6. 其他实例

  • 把用户输入的不规范的英文名字,变为首字母大写,其他小写的规范名字

    1. list1 = ['adam', 'LISA', 'barT']
    2. list(map(lambda x:x.capitalize(),list1))
  • 将一个数字字符串转换为整数的list

    1. list(map(int,'1234'))
  • 提取字典中的key

    1. list(map(int,{1:2,2:3,3:4}))
  • 快速生成26个英文字符

    1. "".join(map(chr, range(ord('a'), ord('z') + 1)))
  • 统计指定字符串每个字符出现的次数,从高到底排列

    1. from collections import Counter
    2. string = "AAABBCCAC"
    3. print("".join(map(lambda x: x[0] + str(x[1]), Counter(string).most_common()))) #A4C3B2

在pandas中大量存在map等应用

filter 过滤

  • 筛选满足条件的元素时非常有用

定义

  1. class filter(object)
  2. | filter(function or None, iterable) --> filter object
  3. |
  4. | Return an iterator yielding those items of iterable for which function(item)
  5. | is true. If function is None, return the items that are true.
  6. |
  7. | Methods defined here:
  8. |
  9. | __getattribute__(self, name, /)
  10. | Return getattr(self, name).
  11. |
  12. | __iter__(self, /)
  13. | Implement iter(self).
  14. |
  15. | __next__(self, /)
  16. | Implement next(self).
  17. |
  18. | __reduce__(...)
  19. | Return state information for pickling.
  20. |
  21. | ----------------------------------------------------------------------
  22. | Static methods defined here:
  23. |
  24. | __new__(*args, **kwargs) from builtins.type
  25. | Create and return a new object. See help(type) for accurate signature

实例

1. 找出整数列表中的奇数

  1. nums = [1,2,3,4,5]
  2. list(filter(lambda x:x%2==1,nums))

2. 找出姓名长度不超过5个字符的人员信息

  1. names = ['alice','jordan','richardson','mike','hudson']
  2. list(filter(lambda x:len(x)<=5,names))

3. 求所有的水仙花数

  1. list(filter(lambda num:int(str(num)[0])**3+int(str(num)[1])**3+int(str(num)[2])**3 == num,range(100,1000)))

4. 剔除所有空字符串

  1. def not_empty(s):
  2. return s and s.strip()
  3. list(filter(not_empty, ['A', '', 'B', None, 'C', ' ']))

reduce 递推

reduce是相对来说比较难的一个函数,一方面是不常用,但在某些应用场景中用它就非常巧妙,另外一方面这个递推的过程你得理解。

定义

  1. reduce(...)
  2. reduce(function, sequence[, initial]) -> value
  3. Apply a function of two arguments cumulatively to the items of a sequence,
  4. from left to right, so as to reduce the sequence to a single value.
  5. For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates
  6. ((((1+2)+3)+4)+5). If initial is present, it is placed before the items
  7. of the sequence in the calculation, and serves as a default when the
  8. sequence is empty.
  • 此处的example对理解reduce非常重要

    1. reduce(lambda x, y: x+y, [1, 2, 3, 4, 5])
    2. --->
    3. ((((1+2)+3)+4)+5)
  • 有个递归的意思在里面from functools import reduce

实例

1. 把[1,3,5,7,9]变成13579

  1. from functools import reduce
  2. reduce(lambda x,y:10*x+y, [1, 3, 5, 7, 9])
  • 注意reduce在functools下面,需要导入

2. 对整数列表中的奇数元素进行求平方

  1. items = [12, 5, 7, 10, 8, 19]
  2. list(map(lambda x: x ** 2, filter(lambda x: x % 2, items)))
  3. # 其实用 列表推导式反而简单了
  4. items = [12, 5, 7, 10, 8, 19]
  5. [x ** 2 for x in items if x % 2]

3. 实现str->int的转换

  1. from functools import reduce
  2. DIGITS = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}
  3. def char2num(s):
  4. return DIGITS[s]
  5. def str2int(s):
  6. return reduce(lambda x, y: x * 10 + y, map(char2num, s))
  7. string = '135'
  8. print(str2int(string))

4. 对列表中所有数字相乘

  1. from functools import reduce
  2. def prod(L):
  3. return reduce(lambda x,y:x*y,L)
  4. print('3 * 5 * 7 * 9 =', prod([3, 5, 7, 9]))
  5. if prod([3, 5, 7, 9]) == 945:
  6. print('测试成功!')
  7. else:
  8. print('测试失败!')

sorted 排序

sorted是python的内置函数,可以排序容器,并且自己定义排序的策略

定义

  1. sorted(iterable, /, *, key=None, reverse=False)
  2. Return a new list containing all items from the iterable in ascending order.
  3. A custom key function can be supplied to customize the sort order, and the
  4. reverse flag can be set to request the result in descending order.
  • reverse可以用来改变正序->倒序
  • key可以用来自定义排序规则

实例

1. 常规正序倒序

  1. list1 = [1,3,5,2,4,6]
  2. sorted(list1) # [1, 2, 3, 4, 5, 6]
  3. sorted(list1,reverse=True) # [6, 5, 4, 3, 2, 1]

2. 字典的key排序

  1. dict1 = {"zhangsan":18,"lisi":20,"wangwu":23,"hanmeimei":22}
  2. sorted(dict1) # ['hanmeimei', 'lisi', 'wangwu', 'zhangsan']
  • dict的sorted得到的结果就是按key来排序

3. 多维数据的排序

  1. list1 = [('A',3,200),('C',1,100),('B',2,300)]
  2. sorted(list1,key=lambda x:x[1])
  3. # [('C', 1, 100), ('B', 2, 300), ('A', 3, 200)]
  4. sorted(list1,key=lambda x:x[0],reverse=False)
  5. # [('A', 3, 200), ('B', 2, 300), ('C', 1, 100)]
  6. sorted(list1,key=lambda x:x[2])
  7. # [('C', 1, 100), ('A', 3, 200), ('B', 2, 300)]

4. 根据字符串的长度排序

  1. urls=['http://c.biancheng.net',
  2. 'http://c.biancheng.net/python/',
  3. 'http://c.biancheng.net/shell/',
  4. 'http://c.biancheng.net/java/',
  5. 'http://c.biancheng.net/golang/']
  6. sorted(urls,key=lambda x:len(x))

5. 根据切割后的字典序(忽略大小写)

  1. sorted("This is a test string from Andrew".split(), key=str.lower)
  2. # ['a', 'Andrew', 'from', 'is', 'string', 'test', 'This']

6. 自定义类的排序

  1. class Person:
  2. def __init__(self,name,age):
  3. self.name = name
  4. self.age = age
  5. def __repr__(self):
  6. return self.name
  7. infos = [Person("wuxianfeng",18),Person("zhangsan",23),Person("lisi",21)]
  8. sorted(infos,key=lambda per:per.age) # [wuxianfeng, lisi, zhangsan]

Python函数式编程之map/filter/reduce/sorted的更多相关文章

  1. Python函数式编程之map()

    Python函数式编程之map() Python中map().filter().reduce()这三个都是应用于序列的内置函数. 格式: map(func, seq1[, seq2,…]) 第一个参数 ...

  2. python 内置函数 map filter reduce lambda

    map(函数名,可遍历迭代的对象) # 列组元素全加 10 # map(需要做什么的函数,遍历迭代对象)函数 map()遍历序列得到一个列表,列表的序号和个数和原来一样 l = [2,3,4,5,6, ...

  3. Python函数式编程中map()、reduce()和filter()函数的用法

    Python中map().reduce()和filter()三个函数均是应用于序列的内置函数,分别对序列进行遍历.递归计算以及过滤操作.这三个内置函数在实际使用过程中常常和“行内函数”lambda函数 ...

  4. python 函数式编程之lambda( ), map( ), reduce( ), filter( )

    lambda( ), map( ), reduce( ), filter( ) 1. lambda( )主要用于“行内函数”: f = lambda x : x + 2 #定义函数f(x)=x+2 g ...

  5. Python函数式编程之lambda表达式

    一:匿名函数的定义 lambda parameter_list: expression 二:三元表达式 条件为真时返回的结果 if 条件判断 else 条件为假的时候返回的结果 三:map map(f ...

  6. Python面试题之Python中的lambda map filter reduce zip

    当年龟叔想把上面列出来的这些都干掉.在 “All Things Pythonic: The fate of reduce() in Python 3000”这篇文章中,他给出了自己要移除lambda. ...

  7. python之内置函数:map ,filter ,reduce总结

    map函数: #处理序列中的每个元素,得到的结果是一个'列表',该列表元素个数及位置与原来一样 filter函数: #遍历序列中的每个元素,判断每个元素得到一个布尔值,如果是true,则留下来 peo ...

  8. python函数式编程之yield表达式形式

    先来看一个例子 def foo(): print("starting...") while True: res = yield print("res:",res ...

  9. Swift函数编程之Map、Filter、Reduce

    在Swift语言中使用Map.Filter.Reduce对Array.Dictionary等集合类型(collection type)进行操作可能对一部分人来说还不是那么的习惯.对于没有接触过函数式编 ...

  10. python常用函数进阶(2)之map,filter,reduce,zip

    Basic Python : Map, Filter, Reduce, Zip 1-Map() 1.1 Syntax # fun : a function applying to the iterab ...

随机推荐

  1. 解决“fast-forward, aborting”问题

    1. 现象 对某一个远程仓库 git pull 过程中,报错如下: # zl @ srv123 in ~/git/radxa/kernel [14:09:54] $ git pull remote: ...

  2. c#使用Bitmap绘图的时候,内存增大问题

    最近碰到一个问题,就是使用Biamap绘图的时候,为了防止闪烁,使用了双缓存绘制的方式,但是会碰到内存急剧增加的情况,而且在XP的工控机和Win10的机器上运行结果不一样,在Win10 上运行的时候, ...

  3. AI赋能音乐创作,人人都是音视频创作者

    华为HMS Core音频编辑服务(Audio Editor Kit)依托自身AI技术的研发优势,上线全新的歌声合成音色及伴奏,给音视频创作者提供更多的创作可能.在短视频场景中,用户自定义歌词的歌声结合 ...

  4. React综合使用联系

    index.js import React from 'react' import ReactDOM from 'react-dom' import CartSimple from './CartSi ...

  5. 【极客时间】大数据概述及HDFS介绍

  6. 保存sklearn中模型的两种方法(pickle、joblib)

    保存sklearn中模型的两种方法(pickle.joblib) from sklearn import svm from sklearn import datasets clf = svm.SVC( ...

  7. 万字干货|Synchronized关键字详解

    作者:小牛呼噜噜 | https://xiaoniuhululu.com 计算机内功.JAVA底层.面试.职业成长相关资料等更多精彩文章在公众号「小牛呼噜噜」 前言 大家好,我是呼噜噜,在之前的文章中 ...

  8. java中生成随机数

    本文主要讲述java中如何生成随机数. public class RandomTest { public static void main(String[] args) { // 生成随机数 方法1: ...

  9. easygui的简单使用——实现猜字谜小游戏

    游戏:随机生成个谜底,每轮有3次机会,猜对了结束本轮游戏,猜错了提示猜大了还是猜小了,并显示剩余次数,3次用完后本轮字谜游戏结束,可重新开始猜字谜,也可结束游戏 # 使用 easygui 实现猜字谜游 ...

  10. [编程基础] C++多线程入门5-使用互斥锁解决资源竞争

    原始C++标准仅支持单线程编程.新的C++标准(称为C++11或C++0x)于2011年发布.在C++11中,引入了新的线程库.因此运行本文程序需要C++至少符合C++11标准. 文章目录 5 使用互 ...