码迷,mamicode.com
首页 > 其他好文 > 详细

第二十四天

时间:2018-08-16 23:45:29      阅读:221      评论:0      收藏:0      [点我收藏+]

标签:16px   split   部分   严格   turn   tools   表达   应用   面向   

函数式编程
"""
函数式编程
不是任何语言都能实现函数式编程。

面向对象:解决类和类之间关系,解决工程的规范化。应对需求的不停改动的问题。
函数式编程:一起去解决程序运行速度和单纯的数学公式的问题。
"""

"""
函数和函数式编程。
函数:定义一个函数,或者一个方法,完成某一项特定的功能。
函数式编程:很多函数作用于一个输入上,给一个固定的输出。
C(B(A(参数)))
"""
# 鸟群合并 :合并:两个鸟群数量相加, 繁衍:两个鸟群相乘
"""
a b c
a和c先合并,再b繁衍
a和b再进行繁衍
再将上面两个大鸟群合并
"""
# class Birds:
# def __init__(self,n):
# self.n=n
# # 合并
# # other代表另外一个鸟群
# def conjoin(self,other):
# self.n=self.n+other.n
# return self
# # 繁衍
# def bread(self,other):
# self.n=self.n * other.n
# return self
# bird_a=Birds(4)
# bird_b=Birds(2)
# bird_c=Birds(0)
# # a和c先合并,再b繁衍4*2=8
# # a和b再进行繁衍4*2=8
# # 将两个大鸟群合并8+8=16
# bird_1=bird_a.conjoin(bird_c).bread(bird_b)
# bird_2=bird_a.bread(bird_b)
# result=bird_1.conjoin(bird_2)
# print(result.n)
from operator import add, mul

def conjoin(x, y):
return x + y

def bread(x, y):
return x * y

bird_a = 4
bird_b = 2
bird_c = 0

result = conjoin(bread(conjoin(bird_a, bird_c), bird_b), bread(bird_a, bird_b))
print(result)

# 将原来的方法改成python固有的方法
result = add(mul(add(bird_a, bird_c), bird_b), mul(bird_a, bird_b))
print(result)

# 结合律,交换律,分配律
# add(add(x,y),z)==add(x,add(y,z))
# add(x,y)==add(y,x)
# mul(x,add(y,z))=add(mul(x,y),mul(x,z))
result = add(mul(bird_a, bird_b), mul(bird_a, bird_b))
mul(bird_a, add(bird_b, bird_b))
print(result)

# 函数式编程:首先要看输入,其次要尽量使用系统内部的方法,最后要尽量缩减整个函数

# 几个相关的重要概念
1. 头等函数:函数可以像变量一样,能够被赋值,能够被修改,能够被传递,能够被返回。
如果支持函数式编程,需要函数必须是头等函数
def e(a, b, **kwargs):
return a * b

print(type(e))

2.匿名函数lambda:当函数体比较简单的时候,可以使用lambda表达式对函数进行提取
lambda 参数: 返回值表达式
def s(k):
return k + 1

f = lambda k: k + 1
print(f(20))

3.嵌套函数和闭包
# def outer():
# def inner():
# pass
# return inner()
def outer():
def inner():
pass

return inner

# 计算一个数x的n倍
def m(x, n):
return x * n

m(2, 3)
m(5, 3)
m(8, 3)

def make_mul(n):
def inner(x):
return x * n
return inner

times3 = make_mul(3)
times3(2)
times3(5)
time5 = make_mul(5)
time5(2)

# 高阶函数
# 初阶函数:一阶函数
# 高阶函数:至少满足下列条件中的一个:
"""
1. 接受一个或者多个函数作为输入
2. 输出一个函数
"""

def make_mul(n):
def inner(x):
return x * n

return inner

time3 = make_mul(3)
time5 = make_mul(5)
# 函数调用可以看成从右到左
time5(time3(2))

# 使用可变类型的值传递,也可以达到高阶函数的效果
def a(x):
x += 1
return list({1, x, 8})


def b(y):
y.append(100)
return y

print(b(a(4)))

(一) 常见的高阶函数
#
1. sort
li = [1, 3, -5, 7]


def s(k):
return abs(k)


li.sort(key=s)
print(li)
li.sort(key=lambda k: abs(k))


2. map 按函数规则改变元素
map(fun,iterable)
fun:函数的名字 iterable: 可迭代对象
map可以将迭代对象中的每一个元素都按照fun函数进行执行,并返回。返回之后是一个迭代对象,
只能遍历或者next
def square(n):
return n * n

li = [1, 3, 5, 7, 9]
result = map(square, li)
print(result)
# result.__next__()
print(next(result))
print(next(result))
for i in result:
print(i)

3. filter 按照过滤条件,过滤每一个元素
filter(fun,可迭代对象)
对可迭代对象中的每一个元素,调用一次函数fun,将元素传入获得返回值
对返回值是True的元素,则保留,否则删除
f = filter(lambda n: n > 5, li)
print(f)
for i in f:
print(i)
4.reduce functools下的方法,按照函数二变一
import functools

functools.reduce(fun,可迭代对象)
li = list(range(1, 11))
# [1,2,3,4,5,6...10]
# x=1 y=2
# x=x+y=3
# y=3
# x=x+y=6
# y=4
# x=x+y=10
# y=5

最终得到一个结果,所以可以直接print
print(functools.reduce(lambda x, y: x + y, li)) # li元素的累加和

# 求元素的最大值
print(functools.reduce(lambda x, y: x if x > y else y, li))

5.max
max(1, 2, 3, -6)
max((2, 4, 5, 6))
max(iterable,key)
能够将每个元素应用key函数,获得返回值,取所有值中的最大值。
year_cheese = [(2000, 35.1), (2001, 33.1), (2002, 33.4), (2003, 33.9)]
print(max(year_cheese, key=lambda k: k[1]))

(二)数据的不可变性
"""
函数式编程是所有的输出都依赖于输入。要求同一个输入,永远得到同一个输出。
要求函数式编程,严格控制数据的输入输出,所以在函数式编程中,
一般选用元组或者命名元组作为输入和输出
将传递进来的变量使用wrapper模式进行处理,变成不可变类型
unwrap(process(wrap(参数)))
"""
from toolz import second

year_cheese = [(2000, 35.1), (2001, 33.1), (2002, 33.4), (2003, 33.9)]
# (35.1,(2000,35.1))
y = (2000, 35.1)
l1 = map(lambda y: (y[1], y), year_cheese)
# print(list(l1))
print(max(map(lambda y: (y[1], y), year_cheese)))
l2 = max(map(lambda y: (y[1], y), year_cheese))
snd = lambda y: y[1]
print(second(max(map(lambda y: (y[1], y), year_cheese))))

# 函数式编程:将参数传入一个函数中,经过n函数,最后有一个输入
# 而输入输出都是不可变的。

# 纯函数/无副作用
# 头等函数、嵌套函数、闭包、高阶函数------需要一个纯函数。
# 纯函数:相同的输入,永远得到相同的输出,而且没有任何可观察的副作用。
# 副作用:print sleep 调用了模块。
# 为了达到纯函数的目的
# 1. 只使用本地变量,避免声明全局变量
x = 1

def add(y):
global x
print(x + y)
x += 1

add(10)
add(10)

# 2.如果需要一个变量在作用域之外使用,可以使用闭包解决
def add(y):
x = 1
print(x + y)
x += 1

add(10)
add(10)

# 纯函数的优点
# 1.一个结果的目的能够是做缓存。
# 2.可以进行移植
# 3.类似于map作为高阶函数,只能接受纯函数,在使用并行计算时,会用到map

# 引用透明度(纯函数)
# 引用透明:返回值只依赖于输入值。

operator模块
"""
operator
"""
from operator import *
1. 算数运算
a=1
b=2
# a+b
print(add(a,b))
print(mul(a,b))
print(mod(a,b))

2. 逻辑运算
a=[1]
b=[1]
print(not_(a))
print(is_(a,b))

3. 比较,返回布尔类型
a=3
b=5
for func in [lt,le,eq,ne,ge,gt]:
print("{}(a,b)".format(func.__name__),func(a,b))
# 效果等价
print(lt(a,b))
print(a<b)
lt(a,b) #a<b
le(a,b) #a<=b

4.原地操作
# add 和 iadd
# iadd对不可变类型来说,作用add是一样
a=3
b=6
iadd(a,b)
print(a)
# 对于可变类型来说iadd是原地增加
a=[1,2,3]
b=[4]
# print(iadd(a,b))
# print(a)
iconcat(a,b)
print(a)

itertools模块
"""
itertools:是python 内置模块
"""
import itertools
import operator
1. 无限循环式迭代
count(start,step)
返回迭代器,获取均匀的间隔值,从传入的start开始,作为起始,step如果不写默认1
for i in itertools.count(10):
if i>15:
break
else:
print(i)

for i in itertools.count(10,1):
if i>15:
break
else:
print(i)

2.cycle(iterator)
创建一个循环遍历一些值的迭代器,产生迭代器
count=0
for i in itertools.cycle("xyz"):
if count>5:
break
print(i)
count+=1

3.repeat(object,[time])
返回重复的迭代器,永远返回同一个对象 ,可以通过time设置次数
i=itertools.repeat(5,3)
print(next(i))
print(next(i))
print(next(i))
# print(next(i))

按输入终止迭代
1.itertools.accumulate 累积迭代器
# 默认按照累加的结果
# [1,2,3,4]
# 1
# 1+2
# 1+2+3
# 1+2+3+4
print(list(itertools.accumulate(range(1,5))))

# 可以指定 运算符
print(list(itertools.accumulate(range(1,5),operator.mul)))

2.groupby(iterable,key)
# 把排好序的迭代对象,按照key中指定的函数,进行分组
# 返回值中的每一个元素都是一个元组
# 一定要先排序
datas=[("A",111),("B",222),("C",333),("A",444),("C",555),("D",666)]
datas_new=sorted(datas)
print(datas_new)
f=lambda x:x[0]
for k,g in itertools.groupby(datas_new,f):
# print(k,g)
for m,n in g:
print("{} is {}".format(m,n))

3. tee(iterable,n) 从单个迭代器中创建n个同样的迭代器
data="ABCDE"
it1,it2,it3=itertools.tee(data,3)
for i in it1:
print(i)
for i in it2:
print(i)
for i in it3:
print(i)

组合生成器
1.itertools.combinations(iterable,r) r代表分组几个元素为一组
print(list(itertools.combinations("WXYZ",3)))

2.itertools.combinations_with_replacement 使用方式同上,包含重复的元素
print(list(itertools.combinations_with_replacement("WXYZ",3)))

3.product(*iterable,repeat=1)返回笛卡尔积
# (1,2)*(4,5)=(1,4)(1,5)(2,4)(2,5)
a=[(-1,1),(-3,3),(5,-5)]
# -1,-3, -1,3 1,-3 1,3 *-5,5

print(list(itertools.product(* a)))

4. permutations 排列,其余跟itertools.combinations一样
print(list(itertools.permutations("WXYZ",3)))

functools模块
"""
functools
"""
from functools import partial
from toolz import frequencies,compose
1、 partial : 局部函数
柯里化函数:在python就是局部函数
使用函数的时候,只传递给函数一部分参数,调用后让他返回另外一个函数,去处理剩下的参数。
# def fun(a,b):
# pass
# x=fun(a)
# x(b)
# fun(a,b)
#n倍乘,闭包
# def mul(n,x):
# # return n*x
# # 希望只传入n获得函数。
# def mulfun(n):
# def inner(x):
# return n*x
# return inner
# times3=mulfun(3)
# times3(10)

# mulfun(3,10)
# partial可以解决函数柯里化的问题
新函数=partial(原函数,一个参数)
新函数(另外一个参数)
等价于:原函数(一个参数,另外一个参数)
def mul(n,x):
return "{}*{}={}".format(n,x,n*x)
#3倍乘法,n=3
time3=partial(mul,3)
print(time3(10))

# 传递参数的时候,如果不传入命名关键字参数,那么传入参数按照第一个位置参数来赋值。
# 已知x=10
x10=partial(mul,x=10)
print(x10(3))

# 安装toolz模块:后台,执行pip install toolz

# 需求:统计字符串中每一个英文单词出现的次数:
# A friend in need is a friend indeed.
# 思路:
"""
1. 使用空格分隔出每一个单词
2. 去掉每一个单词前后的特殊符号
3. 将所有的字符小写
4. 统计
"""
temp_str="A friend in need is a friend indeed."
# 按照空格分隔
li=temp_str.split(" ")
print(li)
# 使用map能够处理每一个元素,能用for解决的问题用map解决
# map(fun,iterable)
def stem(word):
return word.lower().rstrip(".!,").lstrip(".!,")
print(list(map(stem,li)))

使用frequencies计算频次
print(frequencies(map(stem,li)))

# 尝试柯里化函数解决
map_new=partial(map,stem)
result=map_new(temp_str.split(" "))
print(list(map_new(temp_str.split(" "))))
print(frequencies(map_new(temp_str.split(" "))))

# compose:组合函数
# compose(f1,f2,f3) 从右到左
# 组合的结果会返回新的函数。
# f1(f2(f3(参数)))
wordcount=compose(frequencies,partial(map,stem),str.split)
print(wordcount(temp_str))

# 练习
# pow(x,y)
# 1.自己重新实现以下power函数
# 2.通过局部函数的形式调用



第二十四天

标签:16px   split   部分   严格   turn   tools   表达   应用   面向   

原文地址:https://www.cnblogs.com/ztx695911088/p/9490701.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!