python - 函数式编程1

作者:编程技术

本条内容自身是参照廖雪峰的博客,摘抄当中部分剧情而来的,附带消逝他最后的标题代码。

python基础——map/reduce

  

  Python内建了map()reduce()函数。

  假使您读过谷歌的那篇名扬天下标诗歌“MapReduce: Simplified Data Processing on Large Clusters”,你就会差相当少精通map/reduce的概念。

  大家先看map。map()函数选用多个参数,二个是函数,四个是Iterablemap将盛传的函数依次作用到行列的各种成分,并把结果作为新的Iterator返回

  举例表明,比方大家有叁个函数f(x)=x2,要把那些函数成效在一个list [1, 2, 3, 4, 5, 6, 7, 8, 9]上,即可用map()贯彻如下:

 

图片 1

  今后,大家用Python代码完毕:

>>> def f(x):
...     return x * x
...
>>> r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> list(r)
[1, 4, 9, 16, 25, 36, 49, 64, 81]

map()传扬的率先个参数是f,即函数对象自己。由于结果r是一个IteratorIterator是惰性体系,由此通过list()函数让它把任何连串都总计出来并重返叁个list

  你或者会想,没有必要map()函数,写一个循环,也能够总括出结果:

L = []
for n in [1, 2, 3, 4, 5, 6, 7, 8, 9]:
    L.append(f(n))
print(L)

  的确能够,可是,从上边的循环代码,能一眼看理解“把f(x)作用在list的每三个因素并把结果生成一个新的list”吗?

  所以,map()作为高阶函数,事实上它把运算法则抽象了,因而,大家不光能够测算简单的f(x)=x2,还足以估测计算任性复杂的函数,比方,把这些list全数数字转为字符串:

>>> list(map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
['1', '2', '3', '4', '5', '6', '7', '8', '9']

  只需求生龙活虎行代码。

  再看reduce的用法。reduce把一个函数成效在多个行列[x1, x2, x3, ...]上,这一个函数必得接收八个参数,reduce把结果一而再再而三和系列的下三个因素做累积计算,其成效就是:

reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)

  比如说对叁个类别求和,就能够用reduce实现:

>>> from functools import reduce
>>> def add(x, y):
...     return x   y
...
>>> reduce(add, [1, 3, 5, 7, 9])
25

  当然求和平运动算能够一向用Python内建函数sum(),没须求选用reduce

  但是只要要把种类[1, 3, 5, 7, 9]改换到整数13579reduce就足以派上用项:

>>> from functools import reduce
>>> def fn(x, y):
...     return x * 10   y
...
>>> reduce(fn, [1, 3, 5, 7, 9])
13579

  那一个例子本人没多大用途,但是,假设虚构到字符串str也是一个队列,对地点的例证稍加改变,协作map(),大家就能够写出把str转换为int的函数:

>>> from functools import reduce
>>> def fn(x, y):
...     return x * 10   y
...
>>> def char2num(s):
...     return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s]
...
>>> reduce(fn, map(char2num, '13579'))
13579

  收拾成多个str2int的函数就是:

from functools import reduce

def str2int(s):
    def fn(x, y):
        return x * 10   y
    def char2num(s):
        return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s]
    return reduce(fn, map(char2num, s))

  还是能够用lambda函数进一层简化成:

from functools import reduce

def char2num(s):
    return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s]

def str2int(s):
    return reduce(lambda x, y: x * 10   y, map(char2num, s))

  也正是说,借使Python未有提供int()函数,你完全可以和睦写一个把字符串转变为整数的函数,况且只需求几行代码!

  lambda函数的用法在末端介绍。

 

  1.  这是自身在C/C 中绝非见过的语法(大概是自己学艺未精),驾驭它的确花了十来二十二分钟。它提供了一条google的舆论链接:“MapReduce: Simplified Data Processing on Large Clusters",据他们说是意气风发篇很牛逼的篇章。当本身晓得了那几个定义后,感到实在很方便。
  2. 先看map。map()函数选取五个参数,三个是函数,一个是Iterablemap将盛传的函数依次成效到行列的各种成分,并把结果作为新的Iterator返回。

    比方表达,举个例子大家有三个函数f(x)=x2,要把那么些函数效能在二个list [1, 2, 3, 4, 5, 6, 7, 8, 9]上,就足以用map()落实如下:

练习

  1、利用map()函数,把客商输入的不正规的阿尔巴尼亚语名字,变为首字母大写,别的小写的标准名字。输入:['adam', 'LISA', 'barT'],输出:['Adam', 'Lisa', 'Bart']

#练习一:
'''
利用map()函数,把用户输入的不规范的英文名字,变为首字母大写,其他小写的规范名字。
输入:['adam', 'LISA', 'barT'],输出:['Adam', 'Lisa', 'Bart']:
'''
def normalize(name):    #name为一个字符串
    name=name[0].upper() name[1:].lower()    #name[0]表示字符串的首字符
    return name


res=map(normalize,['lINdA','TOM','pAUlA','iSelYONA'])    #将normalize()函数依次作用于'lINdA'
#'TOM' 'pAUlA' 和'iSelYONA'
print(list(res))

  

  运作结果:

  图片 2

  

  2、Python提供的sum()函数能够采纳叁个list并求和,请编写一个prod()函数,能够接纳三个list并利用reduce()求积:

#练习二:
'''
Python提供的sum()函数可以接受一个list并求和,请编写一个prod()函数,
可以接受一个list并利用reduce()求积
'''

def prod(L):    #L为一个list
    def Mult(x,y):
        return x *y

    return reduce(Mult,L)

L1=[3,5,7,9]
print(prod(L1))

  

  运维结果:

      图片 3

 

  3、利用mapreduce编排多个str2float函数,把字符串'123.456'转变来浮点数123.456

#练习三:
'''
利用map和reduce编写一个str2float函数,把字符串'123.456'转换成浮点数123.456:
'''

def str2float(s):
    s=s.split('.')            #以'.'分割字符串

    def f_int(x,y):            #计算整数部分
        return x*10  y

    def f_dec(x,y):            #计算小数部分
        return x/10  y

    def char2num(s):
        return {'0':0,'1':1,'2':2,'3':3,'4':4,'5':5,'6':6,'7':7,'8':8,'9':9}[s]

    return reduce(f_int,map(char2num,s[0]))   reduce(f_dec,list(map(char2num,s[1]))[::-1])/10
    #[::-1]翻转list 注意最后还得除以10,因为reduce处理完之后是4.56,还得将小数点往前移一位
print(str2float('123.456'))

 

 

  运作结果:

     图片 4

 

即使, python未有提供 int() 函数, 我们完全能够自个儿写三个把字符串转化为评释的函数, 并且只必要几行代码. 

  1. 再看reduce的用法。reduce把一个函数效率在三个种类[x1, x2, x3, ...]上,这么些函数必需选择七个参数,reduce把结果一而再和体系的下一个成分做储存计算,其功能便是:

    reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
    
    比方说对一个序列求和,就可以用reduce实现:
    
    >>> from functools import reduce
    >>> def add(x, y):
    ...     return x   y
    ...
    >>> reduce(add, [1, 3, 5, 7, 9])
    25
    

    其生龙活虎例子本人没多大用项,不过,假设设想到字符串str也是二个行列,对地方的事例稍加改变,同盟map(),大家就能够写出把str转换为int的函数:

    >>> from functools import reduce
    >>> def fn(x, y):
    ...     return x * 10   y
    ...
    >>> def char2num(s):
    ...     digits = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}
    ...     return digits[s]
    ...
    >>> reduce(fn, map(char2num, '13579'))
    13579
    

     

  2. ### 练习

    1. 利用map()函数,把顾客输入的不标准的波兰语名字,变为首字母大写,其余小写的正经八百名字。输入:['adam', 'LISA', 'barT'],输出:['Adam', 'Lisa', 'Bart']

      #-*- coding: utf-8 -*-
      def normalize(name):
          return name.capitalize()
      
      # 测试:
      L1 = ['adam', 'LISA', 'barT']
      L2 = list(map(normalize, L1))
      print(L2)
      

       

    2. Python提供的sum()函数能够选拔叁个list并求和,请编写三个prod()函数,能够承当二个list并选用reduce()求积

      # -*- coding: utf-8 -*-
      from functools import reduce
      
      def prod(L):
          def fn(x,y):
              return x*y
          return reduce(fn,L)
      
      print('3 * 5 * 7 * 9 =', prod([3, 5, 7, 9]))
      if prod([3, 5, 7, 9]) == 945:
          print('测试成功!')
      else:
          print('测试失败!')
      

       

    3. 利用mapreduce编写贰个str2float函数,把字符串'123.456'调换来浮点数123.456

      # -*- coding: utf-8 -*-
      from functools import reduce
      
      def str2float(s):
          DIGITS = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}
          pos = len(s)-s.index(".")-1 #寻找小数位
      
          def char2num(my_str):
              if(my_str != "."):
                  return DIGITS[my_str]
      
          def fn(x,y):
              if y==None:
                  return x
              else:
                  return 10*x y
          return reduce(fn,map(char2num,s))/(10**pos)
      
      print('str2float('123.456') =', str2float('123.456'))
      if abs(str2float('123.456') - 123.456) < 0.00001:
          print('测试成功!')
      else:
          print('测试失败!')
      

       

       

 

 

                f(x) = x * x

                      │
                      │
      ┌────────────--------───┐
      │   │   │   │   │   │   │   │   │
      ▼   ▼   ▼   ▼   ▼   ▼   ▼   ▼   ▼

    [ 1    2    3    4    5    6    7    8    9 ]

      │   │   │   │   │   │   │   │   │
      │   │   │   │   │   │   │   │   │
      ▼   ▼   ▼   ▼   ▼   ▼   ▼   ▼   ▼

    [ 1    4    9   16    25   36   49   64   81 ]

现在,我们用Python代码实现:

    1 >>> def f(x):
    2 ...     return x * x
    3 ...
    4 >>> r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])
    5 >>> list(r)
    6 [1, 4, 9, 16, 25, 36, 49, 64, 81]

`map()`传入的第一个参数是`f`,即函数对象本身。由于结果`r`是一个`Iterator`,`Iterator`是惰性序列,因此通过`list()`函数让它把整个序列都计算出来并返回一个list。
from functools import reduce
def prod(L):
    def func(x, y):
        return x * y
    return reduce(func, L)

L = [3, 5, 7, 9]
print(prod(L))
>>> def f(x):
...     return x * x
...
>>> r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> list(r)
[1, 4, 9, 16, 25, 36, 49, 64, 81]
def normalize(name):
    return name[:1].upper()   name[1:].lower()

L1 = ['adam', 'LISA', 'baarT']
L2 = list(map(normalize, L1))
print(L2)

 

(2) reduce配合map, 把str转换为int

  1. filter

1. map

(2) 和map() 雷同, filter()也摄取贰个函数和叁个队列, 和map()区别的是, filter()把传播的函数依次成效于各类成分, 然后依照返回值是true依然false决定封存仍然甩掉该成分.

 

(4) 练习

>>> from functools import reduce
>>> def add(x, y):
...     return x   y
...
>>> reduce(add, [1, 3, 5, 7, 9])
25

回数是指从左向右读和从右向左读都以同等的数, 比如12321, 909. 请利用filter()滤掉非回数:

选用map() 函数, 把客户输入的不正规的德语名字, 变为首字母大写, 其余小写的科班名字

(1) reduce把叁个函数作用在二个体系[x1,x2,x3, ...]上, 这些函数必需接受五个参数, reduce把结果连续和系列的写二个要素做积攒计算:

from functools import reduce

def str2int(s):
    def fn(x, y):
        return x * 10   y
    def char2num(s):
        return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s]
    return reduce(fn, map(char2num, s))
def is_palindrome(num):
    n=str(num)
    if(n==n[::-1]):
        return num

output = filter(is_palindrome, range(1, 100000))
print(list(output))

(1) filter() 的法力是从二个体系中筛选出切合条件的因素, 过滤体系

(1) map()函数选取三个参数, 二个时函数, 二个时Iterable, map将盛传的函数二回功能到薛烈的各样成分, 并把结果作为新的Iterator再次回到.

(3) 举例, 在一个list中, 删掉偶数, 只保留奇数, 能够那样写:

def not_empty(s):
    return s and s.strip()

list(filter(not_empty, ['A', '', 'B', None, 'C', '  ']))
# 结果: ['A', 'B', 'C']

 

 

>>> list(map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
['1', '2', '3', '4', '5', '6', '7', '8', '9']

(5) 用filter() 那么些高阶函数, 关键在黄华联确落到实处一个筛选函数.

只供给一条代码

(2) map() 作为高阶函数, 事实上它把运算法则抽象了, 因而, 我们不但能够测算轻巧的f(x)=x^2, 还能总计任性复杂的函数, 举个例子, 把这些list全数数字转为字符串:

(5) 练习

 

用filter() 求素数, 总括素数的三个艺术是艾氏筛法

(3) 练习

 

def is_odd(n):
    return n % 2 == 1

list(filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15]))
# 结果: [1, 5, 9, 15]

再举例对三个队列求和, 就足以用reduce完成:

 

输入 ['adam', 'LISA', 'barT'] , 输出 ['Adam', 'Lisa', 'Bart']

 

(6) filter() 函数再次回到的是三个Iterator, 也正是二个惰性系列, 所以要逼迫filter() 实现总计结果, 须要用list()函数得到全部结果并回到list.

#生成器, 生成从3开始的奇数序列
def _old_iter():
    n = 1
    while True:
        n = n   2
        yield n

#筛选函数
def _not_divisible(n):
    return lambda x:x % n > 0

#生成器, 不断的返回下一个素数
def primes():
    yield 2
    it = _old_iter()
    while True:
        n = next(it)
        yield n
        it = filter(_not_divisible(n), it)
#循环打印
for n in primes():
    if n < 200:
        print(n)
    else:
        break

(8) 练习:

(4) 比如, 把三个行列中的空字符串删掉, 能够那样写: 

python提供的sum() 函数能够选取一个list并求和, 请编写一个prod()函数, 能够接纳二个list并利用reduce()求积: 

 

reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)

 

行使map和reduce编写叁个str2float函数, 把字符串'123.456'调换到浮点数123.456

from functools import reduce
def str2float(s):      
    def str2num(s):
        def fn(x,y):
            return x*10 y
        def char2num(s):
            return {'0':0,'1':1,'2':2,'3':3,'4':4,'5':5,'6':6,'7':7,'8':8,'9':9}[s]
        return reduce(fn,map(char2num,s))
    a,b=s.split('.') 
    return str2num(a) 0.1**len(b)*str2num(b)
print(str2float('123.456'))

2. reduce

 

 

 

(7) 例子: 

 

 

 

本文由分分快三计划发布,转载请注明来源

关键词: 分分快三计划 python map&amp;amp reduce [python]