高阶函数,文件

简介:

###############高阶函数#################

一 函数

(1)函数本身也可以赋值给变量,即:变量可以指向函数。

截图:

wKioL1lo3PuyR6haAACw6tIvVv0626.png-wh_50



(2)函数名其实就是指向函数的变量!

截图:

wKioL1lo3cny8PjJAACa2mC8jMk484.png-wh_50


上述操作发现:abs为函数名,给abs=1重新赋值后,abs已不是函数,而是一个整数。




二 高阶函数


变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另

一个函数作为参数,这种函数就称之为高阶函数。


1.map函数

map()函数接收两个参数,一个是函数,一个是序列, map 将传入的函数依次作用到序列的每个元素,并把结果作为新的 list 返回。

(不需要 map() 函数,写一个循环,也可以计算出结果.map函数)

截图:

wKioL1lo3inQUIlWAADN50aItH8676.png-wh_50

练习: 

把这list列表中的所有数字转为字符串;([1,2,3]---['1','2','3'])

截图:


wKiom1lo2NXSbljXAAA6TMSxL_s454.png-wh_50

2.reduce函数


reduce 把一个函数作用在一个序列[x1, x2, x3...]上,这个函数必须接收两个参数,reduce 把结果继续和序列的下一个元素做累积计算。

截图:

wKiom1lo3irAuXdhAACFmOD1ZZc768.png-wh_50

wKiom1lo2OODtIn6AABlA41WNtA211.png-wh_50

wKioL1lo3o2gTYX8AACQ-2GJD1c713.png-wh_50


综合编程:

写出把 str 转换为 int 的函数(eg:'12345'--12345)

截图:


wKioL1lo2N2Q1DE-AABSeg689fk594.png-wh_50


reduce函数map/reduce练习题:


利用 map() 函数,把用户输入的不规范的英文名字,变为首字母大写,其他小写的规范名字。输入: ['adam', 'LISA', 'barT'] ,输出: ['Adam', 'Lisa','Bart'] 。

def fun(x): #####  定义一个函数,

    return x.title()

li = ['adam', 'LISA', 'barT']  ###定义一个列表

print map(fun ,li)


截图:

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

截图:

wKiom1lo38-Dzg5dAACC9xZ46ic113.png-wh_50



3.filter函数


filter() 也接收一个函数和一个序列。和 map() 不同的时,filter() 把传入的函数依次作用于每个元素,然后根据返回值是 True

还是 False 决定保留还是丢弃该元素。


在一个 list 中,删掉偶数,只保留奇数:

截图:

wKiom1lo3o7S9JNzAABLZ9r_T3k249.png-wh_50

在一个 list 中,删掉奇数,只保留偶数:

截图:

wKioL1lo3o7hTBqkAABO_vZl-xk331.png-wh_50


习题:


把一个序列中的空字符串删请尝试用 filter() ;

用 filter()删除 1~100 的素数;



4.sorted函数


排序也是在程序中经常用到的算法。 无论使用冒泡排序还是快速排序,排序的核心是比较两个元素的大小。

通常规定如下:

x < y, return -1

x == y, return 0

x > y, return 1

python内置的 sorted() 函数就可以对 list 进行排序;

如果要倒序排序呢?

如果要对字符串进行排序呢?sorted函数倒序排序



In [1]: t=(12,56,432,56,954)  ####定义一个元组


In [2]: sorted(t)  #####内置函数 :默认从小到大排列

Out[2]: [12, 56, 56, 432, 954]

In [4]: def reversed_cmp(x,y): #####自己定义函数:从大到小排列。(整数)

    if x>y :

   ...:         return -1

   ...:     elif x<y :

   ...:         return 1

   ...:     else:

   ...:         return 0

   ...:     

In [5]: sorted(t,reversed_cmp) ###高阶函数

Out[5]: [954, 432, 56, 56, 12]


In [6]: li=["xiaoming","huangrong"]  ####定义一个列表


In [7]: sorted(li)  #####内置函数 :默认从小到大排列,按字母所对应的acsii码大小排列。

Out[7]: ['huangrong', 'xiaoming']

In [20]: li=['xiaoming', 'huangrong', 'Huangrong']

In [24]: "huangrong">"Huangrong"

Out[24]: True

In [17]: def ignore_case_cmp(x,y):#####自己定义函数:从大到小排列(字母)

    lower1=x.lower()

    lower2=y.lower()

    if lower1<lower2:

        return -1

    elif lower1>lower2:

   ....:         return 1

   ....:     else:

   ....:         return 0

   ....:     

In [21]: sorted(li,ignore_case_cmp)  ###高阶函数

Out[21]: ['huangrong', 'Huangrong', 'xiaoming']




5.函数作为返回值


高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回。

(1)

def lazy_sum(*args):    1

def sum():              5

ax = 0                  6

for n in args:          7

ax = ax + n             8

return ax               9

return sum              3

f = lazy_sum(1,2,3,4)   2    #调用 lazy_sum() 时,返回的并不是求和结果,而是求和函数

f()                    4,10 #调用函数 f 时,才真正计算求和的结果函数作为返回值调用 lazy_sum() 时,每次调用都会返回一个新的函数,即使传入相同的参数


(2)

def warp_sum(*args):定义一个把求和函数作为内置函数的函数:执行显示表达式(闭包)

    def my_sum():  ########定义一个求和的函数:执行直接求和 

        sum_num=0

        for i in args:

            if not isinstance(i,(int,float)):

                print "type error"

            sum_num = sum_num +i

        return sum_num

    return my_sum

f = warp_sum(1,4,2)   ####给函数赋值

print f()   #######打印f

截图:

wKioL1lo2s-Rt0eJAAC1gZ0BA9o562.png-wh_50


(3)

def count(): #########定义一个函数

    fs=[]   ######定义一个空列表

    for i in range(1,4):  ###循环遍历

        def f():

            return i*i

        fs.append(f)  ####将f添加到fs列表,f是函数的存储地址

    return fs

f1,f2,f3,=count()

print f1  ########显示函数的存储地址

print f2

print f3

截图:

wKioL1lo2OWSAcEdAAD886HnvKU724.png-wh_50


(4)

def count():

    fs=[]

    for i in range(1,4):

        def f():

            return i*i

        fs.append(f)

    return fs

f1,f2,f3,=count()

print f1()  #############显示的是数值,可是数值都为9

print f2()

print f3()

截图:

wKioL1lo2tCj2T0VAADbZdlulpo134.png-wh_50


(5)

def count():

    fs=[]

    for i in range(1,4):

        def f(j):

            def g():##########在f函数里嵌套一个g函数

                return j*j

            return g

        fs.append(f(i))

    return fs

f1,f2,f3,=count()

print f1()   ####返回的是各自对应值;1,4,9

print f2()

print f3()

wKiom1lo2tLj0xFhAAEAGv7C9JQ525.png-wh_50


6.匿名函数


因为匿名函数没有名字,不必担心函数名冲突。

匿名函数可以跳过给函数栈分配空间


当我们在传入函数时,有些时候,不需要显式地定义函数,直接传入匿名函数更方便。

关键字 lambda 表示匿名函数,冒号前面的 x 表示函数参数匿名函数

匿名函数有只能有一个表达式,不用写 return ,返回值就是该表达式的结果。

 此外,匿名函数也是一个函数对象,也可以把匿名函数赋值给一个变量,再利用变量来调用该函数;

也可以把匿名函数作为返回值返回


def pow1(x):

    return x*x

print map(pow1,range(1,11))

print map(lambda x:x*x,range(1,11))

f= lambda :1

print f

截图:

wKioL1lo2tPCzglWAADGrmv7EEs422.png-wh_50



f=lambda x,y=2:x**y

print f(2,3)

print (2) 

截图:


wKiom1lo2tSjvwWZAABfwxXqjro899.png-wh_50


f = lambda  *x:map(lambda  x:x+x,x)

print f(1,2,3,4)

wKioL1lo2-7wxNSEAABmXRHY0XE506.png-wh_50

f = lambda  **kwargs:kwargs.items()

print f (name='fentiao',age=5)

wKiom1lo2--hzMxRAABjzBx6M7w709.png-wh_50

x=1

oper = "*"

y = 2

d={

    "+":lambda x,y:x+y,

    "-":lambda x,y:x+y,

    "*":lambda x,y:x*y,

    "/":lambda x,y:x/y

}

if oper not in d.keys():

    print 'input +,-,*,/'

wKioL1lo2_DysSryAADJHwUFoHk943.png-wh_50

wKiom1lo2_GgZFeZAADt718AA-w696.png-wh_50

7 装饰器

装饰器就是用来装饰函数。

不修改函数的源代码。

函数的调用方式没有改变。


想要增强原有函数的功能;

但不希望修改now()函数的定义;

在代码运行期间动态增加功能的方式;装饰器

定义的装饰器实质是返回函数的高阶函数。(试试下面的装饰器)

import time

def timeIt(func):

def warp(arg):

start = datetime.datetime.now()

func(arg)

end = datetime.datetime.now()

cost = end - start

print "execute %s spend %s" % (func.__name__,cost.total_seconds())

return warp

@timeIt # 这里是 python 提供的一个语法糖

def func(arg):

time.sleep(arg)

func(3)


import time

def timmer (func):

    start_time = time.time()

    func()

    stop_time=time.time()

    return stop_time-start_time


def hello2():

    print 'hello2....'

    time.sleep(2)

print timmer(hello2)

print d[oper](x,y)

wKioL1lo2_LSEkBTAADCn0Q2SL4431.png-wh_50


import time

def logger (func):

    def dec():

        start_time = time.time()

        func()

        stop_time=time.time()

        return '%s run %f s'%(func.__name__,stop_time-start_time)

    return dec


@logger

def hello2():

    print 'hello2....'

    time.sleep(2)

print hello2()


wKiom1lo3PrSkUbbAAEE-wv3Zqg277.png-wh_50




#############文件操作#################


一 文件读写

Python 内置了读写文件的函数,用法和 C 是兼容的。

操作系统不允许普通的程序直接操作磁盘,所以,读写文件就是请求操作系统打开一个文件对象(又称文件描述符),然后,通过操作系统提供的接

口从这个文件对象操作;

1.思考:

把大象放进冰箱的过程。


2.思考文件读写的过程:

(1). 打开文件

(2). 向文件中写入内容;

(3). 关闭文件文件读写


3. 打开文件

f = open('/root/hello')

# 如果文件不存在, open() 函数就会抛出一个 IOError 的错误,并且给出错误码和详细的信息告诉你文件不存在;


4.读取文件

f.read()

#如果文件打开成功,接下来,调用 read() 方法可以一次读取文件的全部内容;


5.关闭文件

f.close()

#文件使用完毕后必须关闭,因为文件对象会占用操作系统的资源。



6.思考:

read()会一次性读取文件的全部内容,如果文件有 10G,内存就爆了。怎么解决?

如果文件很小, read() 一次性读取最方便;

如果不能确定文件大小,反复调用 read(size)

比较保险;如果是配置文件,调用 readlines()文件读写

截图:

wKioL1lo4XLwmfzFAACH0MKSFd0944.png-wh_50

wKioL1lo4XSDFPdkAADnIL6aSnU586.png-wh_50

wKioL1lo4c_DfV7KAAEPkoTPMKo075.png-wh_50

7. 二进制文件

要读取二进制文件,比如图片、视频等等,用 'rb' 模式打开文件即可

>>> f = open('/root/test.jpg', 'rb')

>>> f.read()

'\xff\xd8\xff\xe1\x00\x18Exif\x00\x00...' # 十六进制表示的字节文件读写



8. 字符编码

要读取非 ASCII 编码的文本文件,就必须以二进制模式打开,再解码,Python 还提供了一个 codecs 模块帮我们在读文件时自动转换编码,直接读出 unicode。

import codecs

with codecs.open('/Users/michael/gbk.txt', 'r', 'gbk') as f:

f.read() # u'\u6d4b\u8bd5'


二 open函数的模式


r 以读的方式打开,定位到文件开头 , 默认的 mode

r+ 以读写的方式打开,定位文件开头 , 可以写入内容到文件

w 以写的方式打开,打开文件的时候会清空文件的内容,并且不能读

w+ 以读写的方式打开,定位到文件头,并且打开文件的时候也会清空文件的内容

a 以写的方式打开,定位到文件的末尾,是一个追加的操作 , 但并不允许读

a+ 以读写的方式打开,定位到文件的末尾,追加的方式。

在使用以上 mode 打开文件的时候,如果增加了b 模式,表示以二进制方式打开

截图:

wKioL1lo4E_R2Sh_AAFX-tyoEV0318.png-wh_50

wKioL1lo4FGC8qbRAAC7sQ1Pt_w282.png-wh_50

wKiom1lo4FKjYG8FAADFsUur6ls279.png-wh_50

wKioL1lo4FOgUeNkAAC2bNXSiyo155.png-wh_50

wKiom1lo4OSQ2Hx4AAA7Hlk-Uvc823.png-wh_50

wKioL1lo4OfSH189AAB_q5KJKJY773.png-wh_50

wKioL1lo4ObRmV-lAAA6gSGV0Mk069.png-wh_50

wKiom1lo4OijxxsXAABGK_7BGro021.png-wh_50

wKioL1lo4OmQPh_dAABWftZqECY969.png-wh_50


三 文件的其它操作


1.f.flush()函数,将缓冲区的内容写入到硬盘中

2.f.seek(offset[,whence]),offset 表示移动多少字节, whence 为 1 的时候表示相对于当前位置移动的;当 2 的时候从文件的末尾往后移动,但不一定所有的平台都支持;默认为 0 表示从文件开头往后移动

3.f.tell()函数,返回当前文件指针的偏移量:文件的其它操作

4.fileno() 函数,返回当前的文件描述符,一个数字

5.isatty() 函数,当前打开的文件是否是一个终端设备

6.closed 属性,当前文件是否关闭 ,|True,False, f.closed

7.file 对象是一个迭代器:

next() 方法 , 一行一行的读 , 每次读取一行

wKiom1lo4i2Rg4JPAAD9N_ppuNc895.png-wh_50

wKioL1lo4i6A-RuZAAGwSpMK6kw972.png-wh_50

wKioL1lo4i_RkeKrAADBqdFYBWo685.png-wh_50

wKiom1lo4jDjR4QLAADptSl_xos898.png-wh_50


四 with语法



一般情况打开一个文件,经过操作之后,都要显式的执行xx.close() 将文件关闭 .with 用于需要打开、关闭成对的操作,可以自动关闭打开对象 .

with expression as obj:# 将打开的对象赋值给 obj

expression

#obj 的作用域只在 with 语句中


wKioL1lo4iuAj8z3AAC4_LVsaT8834.png-wh_50










本文转自 如何何如  51CTO博客,原文链接:http://blog.51cto.com/12778805/1947733,如需转载请自行联系原作者
目录
相关文章
|
18天前
|
存储 算法
什么是高阶函数
什么是高阶函数
11 1
|
6月前
|
JavaScript 前端开发 Java
函数式编程入门:理解纯函数、高阶函数与柯里化
函数式编程入门:理解纯函数、高阶函数与柯里化
61 0
|
6月前
1 # 高阶函数
1 # 高阶函数
31 0
|
Python
Python(5)高阶函数之返回函数和匿名函数
Python(5)高阶函数之返回函数和匿名函数
77 0
|
Python
Python(6)高阶函数之装饰器和偏函数
Python(6)高阶函数之装饰器和偏函数
85 0
|
分布式计算 Scala 开发者
高阶函数的介绍和使用 | 学习笔记
快速学习高阶函数的介绍和使用
84 0
|
分布式计算 开发者 Python
高阶函数| 学习笔记
快速学习高阶函数
67 0
|
存储 缓存 算法
【Python高级编程】—— 函数式编程总结(生成器、迭代器、匿名函数、高阶函数、返回函数、闭包、装饰器、偏函数)
Python函数式编程的一般概念及特点, 迭代器、生成器表达式、内置函数、常用高阶函数、递归与归约、实用模块和装饰器的用法, 以及避开Python严格求值顺序的变通方法、Web服务设计方法和一些优化技巧。
236 1
【Python高级编程】—— 函数式编程总结(生成器、迭代器、匿名函数、高阶函数、返回函数、闭包、装饰器、偏函数)
|
存储 JavaScript 程序员
【函数式编程】基于JS进行函数式编程(二)高阶函数 | 函数代替数据传递 | 函数是一等公民 | 闭包 | 使用高阶函数实现抽象 | 数组的高阶函数
【函数式编程】基于JS进行函数式编程(二)高阶函数 | 函数代替数据传递 | 函数是一等公民 | 闭包 | 使用高阶函数实现抽象 | 数组的高阶函数
132 0
|
JavaScript 前端开发 Unix
【函数式编程】基于JS进行函数式编程(三)柯里化 | 偏函数 | 组合与管道
【函数式编程】基于JS进行函数式编程(三)柯里化 | 偏函数 | 组合与管道
160 0
【函数式编程】基于JS进行函数式编程(三)柯里化 | 偏函数 | 组合与管道