Python之高级函数-高级程序员与普通程序员的区别

目录

python的高阶函数

1、假如你想从一个考试分数的列表中删除所有的0分,怎么办?

普通程序员:

高级程序员:

2、filter函数

3、给定一个数列[1,3,5,6,7,9,10,435],求数列中每一项相乘的结果

普通程序员

高级程序员:

4、函数的递归和嵌套

通过生成菲波那切数列来演示:


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]

这性能差别也太大了,记住指数级别的增长确实是非常厉害的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章