python之一等函数4

Posted 牛建邦

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python之一等函数4相关的知识,希望对你有一定的参考价值。

#operator模块,在函数式编程中,经常需要把算术运算符当作函数使用。

使用reduce 函数和一个匿名函数计算阶乘

from functools import reduce

def fact(n):

    return reduce(lambda a, b: a*b, range(1, n+1))

#使用reduce operator.mul 函数计算阶乘

from functools import reduce

from operator import mul

def fact(n):

    return reduce(mul, range(1, n+1))

#operator 模块中还有一类函数,能替代从序列中取出元素或读取对象属性的lambda 表达式:itemgetter attrgetter 其实会自行构建函数。itemgetter 的常见用途:根据元组的某个字段给元组列表排序。itemgetter(1) 的作用与lambda fields: fields[1] 一样:创建一个接受集合的函数,返回索引位上的元素。

#使用itemgetter 排序一个元组列表

metro_data = [

    ('Tokyo', 'JP', 36.933, (35.689722, 139.691667)),

    ('Delhi NCR', 'IN', 21.935, (28.613889, 77.208889)),

    ('Mexico City', 'MX', 20.142, (19.433333, -99.133333)),

    ('New York-Newark', 'US', 20.104, (40.808611, -74.020386)),

    ('Sao Paulo', 'BR', 19.649, (-23.547778, -46.635833)),

    ]

 

from operator import itemgetter

for city in sorted(metro_data, key=itemgetter(1)):

    print(city)

"""

('Sao Paulo', 'BR', 19.649, (-23.547778, -46.635833))

('Delhi NCR', 'IN', 21.935, (28.613889, 77.208889))

('Tokyo', 'JP', 36.933, (35.689722, 139.691667))

('Mexico City', 'MX', 20.142, (19.433333, -99.133333))

('New York-Newark', 'US', 20.104, (40.808611, -74.020386))

"""

#如果把多个参数传给itemgetter,它构建的函数会返回提取的值构成的元组:

cc_name = itemgetter(1, 0)

for city in metro_data:

    print(cc_name(city))

"""

('JP', 'Tokyo')

('IN', 'Delhi NCR')

('MX', 'Mexico City')

('US', 'New York-Newark')

('BR', 'Sao Paulo')

"""

#itemgetter 使用[] 运算符,因此它不仅支持序列,还支持映射和任何实现__getitem__ 方法的类。

#attrgetter itemgetter 作用类似,它创建的函数根据名称提取对象的属性。如果把多个属性名传给attrgetter,它也会返回提取的值构成的元组。此外,如果参数名中包含.(点号),attrgetter 会深入嵌套对象,获取指定的属性。这个控制台会话不短,因为我们要构建一个嵌套结构,这样才能展示attrgetter 如何处理包含点号的属性名。

#定义一个namedtuple,名为metro_data,使用attrgetter 处理它

from collections import namedtuple

LatLong = namedtuple('LatLong', 'lat long') # 使用namedtuple 定义LatLong

Metropolis = namedtuple('Metropolis', 'name cc pop coord') # 再定义Metropolis

metro_areas = [Metropolis(name, cc, pop, LatLong(lat, long)) 

                for name, cc, pop, (lat, long) in metro_data]# 使用Metropolis 实例构建metro_areas 列表;注意,我们使用嵌套的元组拆包提取(lat, long),然后使用它们构建LatLong,作为Metropolis coord 属性。

print(metro_areas[0])  #Metropolis(name='Tokyo', cc='JP', pop=36.933, coord=LatLong(lat=35.689722,long=139.691667))

print(metro_areas[0].coord.lat) # 深入metro_areas[0],获取它的纬度。35.689722

from operator import attrgetter

name_lat = attrgetter('name', 'coord.lat') # 定义一个attrgetter,获取name 属性和嵌套的coord.lat 属性。

for city in sorted(metro_areas, key=attrgetter('coord.lat')): # 再次使用attrgetter,按照纬度排序城市列表。

    print(name_lat(city)) # 使用(定义一个attrgetter,获取name 属性和嵌套的coord.lat 属性。)中定义的attrgetter,只显示城市名和纬度。

"""

('Sao Paulo', -23.547778)

('Mexico City', 19.433333)

('Delhi NCR', 28.613889)

('Tokyo', 35.689722)

('New York-Newark', 40.808611)

"""

#operator 模块中定义的部分函数(省略了以开头的名称,因为它们基本上是实现细节):

import operator

print([name for name in dir(operator) if not name.startswith('_')])

#['abs', 'add', 'and_', 'attrgetter', 'concat', 'contains', 'countOf', 'delitem', 'eq', 'floordiv', 'ge', 'getitem', 'gt', 'iadd', 'iand', 'iconcat', 'ifloordiv', 'ilshift', 'imatmul', 'imod', 'imul', 'index', 'indexOf', 'inv', 'invert', 'ior', 'ipow', 'irshift', 'is_', 'is_not', 'isub', 'itemgetter', 'itruediv', 'ixor', 'le', 'length_hint', 'lshift', 'lt', 'matmul', 'methodcaller', 'mod', 'mul', 'ne', 'neg', 'not_', 'or_', 'pos', 'pow', 'rshift', 'setitem', 'sub', 'truediv', 'truth', 'xor']

#开头、后面是另一个运算符的那些名称(如iaddiand 等),对应的是增量赋值运算符(如+=&= 等)。如果第一个参数是可变的,那么这些运算符函数会就地修改它;否则,作用与不带的函数一样,直接返回运算结果。

#operator 模块余下的函数中,我们最后介绍一下methodcaller。它的作用与attrgetteritemgetter 类似,它会自行创建函数。methodcaller 创建的函数会在对象上调用参数指定的方法。

#methodcaller 使用示例:第二个测试展示绑定额外参数的方式

from operator import methodcaller

s = 'The time has come'

upcase = methodcaller('upper')

print(upcase(s)) #'THE TIME HAS COME'

hiphenate = methodcaller('replace', ' ', '-')

print(hiphenate(s)) #'The-time-has-come'

#第一个测试只是为了展示methodcaller 的用法,如果想把str.upper 作为函数使用,只需在str 类上调用,并传入一个字符串参数str.upper(s)。第二个测试表明,methodcaller 还可以冻结某些参数,也就是部分应用(partial application),这与functools.partial 函数的作用类似。

'''

#partial 及其变体,partialmethodfunctools.partial 这个高阶函数用于部分应用一个函数。部分应用是指,基于一个函数创建一个新的可调用对象,把原函数的某些参数固定。使用这个函数可以把接受一个或多个参数的函数改编成需要回调的API,这样参数更少。

#使用partial 把一个两参数函数改编成需要单参数的可调用对象

from operator import mul

from functools import partial

triple = partial(mul, 3#使用mul 创建triple 函数,把第一个定位参数定为3

print(triple(7)) #测试triple 函数。21

print(list(map(triple, range(110)))) #map 中使用triple;在这个示例中不能使用mul[3, 6, 9, 12, 15, 18, 21, 24, 27]

#如果处理多国语言编写的文本,在比较或排序之前可能会想使用unicode.normalize('NFC', s) 处理所有字符串s。如果经常这么做,可以定义一个nfc 函数。

#使用partial 构建一个便利的Unicode 规范化函数

import unicodedata, functools

nfc = functools.partial(unicodedata.normalize, 'NFC')

s1 = 'café'

s2 = 'cafe\u0301'

print(s1, s2) #('café', 'café')

print(s1 == s2) #False

print(nfc(s1) == nfc(s2)) #True

#partial 的第一个参数是一个可调用对象,后面跟着任意个要绑定的定位参数和关键字参数。

#tag 函数上使用partial,冻结一个定位参数和一个关键字参数。把partial 应用到tag 函数上

def tag(name, *contentcls=None, **attrs):

    """生成一个或多个html标签"""

    if cls is not None:

        attrs['class'] = cls

    if attrs:

        attr_str = ''.join(%s="%s"' % (attr, value)

                            for attr, value in sorted(attrs.items()))

    else:

        attr_str = ''

    if content:

        return '\n'.join('<%s%s>%s</%s>' %

                        (name, attr_str, c, name) for c in content)

    else:

        return '<%s%s />' % (name, attr_str)

print(tag) #<function tag at 0x10206d1e0> #tag 函数,查看它的ID

from functools import partial

picture = partial(tag, 'img'cls='pic-frame'#使用tag 创建picture 函数,把第一个定位参数固定为'img',把cls 关键字参数固定为'pic-frame'

print(picture(src='wumpus.jpeg')) #'<img class="pic-frame" src="wumpus.jpeg" />' #picture 的行为符合预期

print(picture) #functools.partial(<function tag at 0x10206d1e0>, 'img', cls='pic-frame') partial() 返回一个functools.partial 对象。

print(picture.func) #functools.partial 对象提供了访问原函数和固定参数的属性。<function tag at 0x10206d1e0>

print(picture.args) #('img',)

print(picture.keywords) #{'cls': 'pic-frame'}

#functools.partialmethod 函数的作用与partial 一样,不过是用于处理方法的。functools 模块中的lru_cache 函数令人印象深刻,它会做备忘(memoization),这是一种自动优化措施,它会存储耗时的函数调用结果,避免重新计算。用作装饰器的其他高阶函数:singledispatch wraps


以上是关于python之一等函数4的主要内容,如果未能解决你的问题,请参考以下文章

4python基本知识点

4Python控制流

4Python标准库系列之sys模块

4Python全站之路系列之sceapy爬虫

4python基础语法

#跟着教程学# 4Python流程控制