目录
3、给定一个数列[1,3,5,6,7,9,10,435],求数列中每一项相乘的结果
python的高阶函数
1、假如你想从一个考试分数的列表中删除所有的0分,怎么办?
普通程序员:
第一步:定义一个函数
def remove_zero(yourList):
newlist = []
for number in yourList:
if number > 0:
newlist.append(number)
return newlist
第二步:在用到该功能的地方调用之
if __name__ == '__main__':
mylist = [12,4,0,23]
print(remove_zero(mylist))
高级程序员:
只有一步,直接上lambda表达式
if __name__ == '__main__':
mylist = [12,4,0,23]
new_l = list(filter(lambda number: number > 0, mylist))
print(new_l)
科普一下,lambda表达式。
lambda表达式不是python的独有武功,java8中也有。说简单点就是你可以把一个匿名函数作为参数传递给另一个函数(方法)。在Python中Lambda的语法是这样的:
lambda <argument list> : <expression>
java8中lambda表达式的语言是这样的:
(parameters) -> expression
没有比较就没有伤害,python的写法依旧是延用":",而且前面的lambda是必须有的,否者会报错。
2、filter函数
filter(isPositive,oldList), 该函数接受2个参数,第一个参数接受一个布尔函数,第二个参数接受一个可迭代对象。所以我们可以给filter函数传入一个lambda表达式。
lambda number: number > 0
filter函数的源代码:
class filter(object):
"""
filter(function or None, iterable) --> filter object
Return an iterator yielding those items of iterable for which function(item)
is true. If function is None, return the items that are true.
"""
def __getattribute__(self, *args, **kwargs): # real signature unknown
""" Return getattr(self, name). """
pass
def __init__(self, function_or_None, iterable): # real signature unknown; restored from __doc__
pass
def __iter__(self, *args, **kwargs): # real signature unknown
""" Implement iter(self). """
pass
@staticmethod # known case of __new__
def __new__(*args, **kwargs): # real signature unknown
""" Create and return a new object. See help(type) for accurate signature. """
pass
def __next__(self, *args, **kwargs): # real signature unknown
""" Implement next(self). """
pass
def __reduce__(self, *args, **kwargs): # real signature unknown
""" Return state information for pickling. """
pass
可迭代对象的每一项都传递给布尔函数,如果该函数返回True,这一项就保留在返回的可迭代对象中;否则的话,删除该项。
3、给定一个数列[1,3,5,6,7,9,10,435],求数列中每一项相乘的结果
普通程序员
第一步:定义一个方法
def list_element_multiplication(oldList):
ret=1
for e in oldList:
ret *= e
return ret
第二步:调用这个方法
# 第一种方法 定义一个函数
list1=[1,2,3,4,5]
print(list_element_multiplication(list1))
高级程序员:
# 第二种方法
print(functools.reduce(lambda x,y: x*y, list1))
高级程序员熟悉python的内建模块和常用的方法,所以他已经将问题与functools.reduce方法相联系,传入lambda表达式和用户列表就轻松完成了工作。
4、函数的递归和嵌套
通过生成菲波那切数列来演示:
# 菲波那切数列 演示函数的递归调用和函数嵌套
def fibonacci(n, product = 1):
if n == 1:
return product
elif n == 2:
return product
else: # 函数的递归调用
return fibonacci(n - 1) + fibonacci(n - 2)
def fibonacci_sequence(n):
f_sequence = []
for x in range(1,n):
f_sequence.append(fibonacci(x)) # 函数的嵌套
return f_sequence
if __name__ == '__main__':
print(fibonacci_sequence(10))
非递归方式生成斐波那契额数列:
# 非递归条用实现斐波那契额数列
def fib(n):
sum = 1
first = 1
second = 1
count =3
while count <= n:
sum = first + second
first = second
second = sum
count +=1
return sum
def fib_sequence(n):
fib_s_list = []
for y in range(1,n):
fib_s_list.append(fib(y))
return fib_s_list
if __name__ == '__main__':
print(fib_sequence(10))
总结:递归方式生成斐波那契数列代码简单,而且优雅,但是存在一个严重的问题,该算法的复杂度是指数阶的。当问题规模比较大时,该算法性能非常差劲。所以计算机科学家设计了另一类实现算法,不需要采用递归的方式进行,该算法的复杂度是线性阶的。
测试:
import time
# 菲波那切数列 演示函数的递归调用和函数嵌套
def fibonacci(n, product = 1):
if n == 1:
return product
elif n == 2:
return product
else: # 函数的递归调用
return fibonacci(n - 1) + fibonacci(n - 2)
def fibonacci_sequence(n):
start = time.time()
f_sequence = []
for x in range(1,n):
f_sequence.append(fibonacci(x)) # 函数的嵌套
end = time.time() - start
print(end)
return f_sequence
# 非递归条用实现斐波那契额数列
def fib(n):
sum = 1
first = 1
second = 1
count =3
while count <= n:
sum = first + second
first = second
second = sum
count +=1
return sum
def fib_sequence(n):
start = time.time()
fib_s_list = []
for y in range(1,n):
fib_s_list.append(fib(y))
end = time.time() - start
print(end)
return fib_s_list
if __name__ == '__main__':
print(fibonacci_sequence(10))
print(fib_sequence(10))
5.316734313964844e-05
[1, 1, 2, 3, 5, 8, 13, 21, 34]
2.09808349609375e-05
[1, 1, 2, 3, 5, 8, 13, 21, 34]
当问题规模是10,递归调用所耗费的时间就已经是非递归调用的2倍多;
当问题规模是40是,测试结果如下:
63.553478956222534
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025, 121393, 196418, 317811, 514229, 832040, 1346269, 2178309, 3524578, 5702887, 9227465, 14930352, 24157817, 39088169, 63245986]
8.20159912109375e-05
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025, 121393, 196418, 317811, 514229, 832040, 1346269, 2178309, 3524578, 5702887, 9227465, 14930352, 24157817, 39088169, 63245986]
这性能差别也太大了,记住指数级别的增长确实是非常厉害的。