Python高级用法总结—(列表推导式,迭代器,生成器,装饰器)

Python高级用法总结—(列表推导式,迭代器,生成器,装饰器)


列表推导式(list comprehensions)

场景1:将一个三维列表中所有一维数据为a的元素合并,组成新的二维列表。 最简单的方法:新建列表,遍历原三维列表,判断一维数组是否为a,若为a,则将该元素append至新列表中。 缺点:代码太繁琐,对于Python而言,执行速度会变慢很多。 针对场景1,我们首先应该想到列表解析式来处理:

lista = [item for item in array if item[0] == 'a’]

那么,什么是列表解析式? 官方解释:列表解析式是Python内置的非常简单却强大的可以用来创建list的生成式 可以看到,使用列表解析式的写法更加简短,除此之外,因为是Python内置的用法,底层使用c语言实现,相较于编写Python代码而言,运行速度更快。 场景2:对于一个列表,既要遍历索引又要遍历元素 这里可以使用Python內建函数enumerate,在循环中更好的获取得到索引

array = ['I’, “love’, 'Python’]for I element in  enumerate(array):
        array[I] = '%d:%s’%(I, element)

可以使用列表推导式对其进行重构

def getitem(index, element):
        return '%d:%s’%(index, element)array = ['I’, 'love’, 'Python’]arrayIndex = [getitem(index, element) for indexm element in enumerate(array)]

总结:如果要对现有可迭代对象做一下处理,然后生成新的列表,使用列表推导式将是最便捷的方法。

迭代器和生成器

迭代器(Iterator)

这的迭代器可以指for循环,在python中,对于像list,dict和文件等而言,都可以使用for循环,但是它们并不是迭代器,它们属于可迭代对象。 什么可迭代对象? 最简单的解释:可以使用for…in…语句进行循环的对象,就是可迭代对象(Iterable),可以使用isinstance()方法进行判断。

from collections import Iterabletype = isinstance('python’, Iterable)print type

什么是迭代器? 迭代器指的是可以使用next()方法来回调的对象,可以对可迭代对象使用iter()方法,将其转换为迭代器。

temp=iter([1, 2, 3])print type(temp)print next(temp)

此时temp就是一个迭代器,所以说,迭代器基于两个方法:

next:返回下一个项目 iter:返回迭代器本身

可以理解为可被next()函数调用并不断返回下一个值的对象就是迭代器,在定义一个装饰器时将需要同时定义这两个方法。

迭代器的优势

在构建迭代器时,不是将所有元素一次性的加载,而是等调用next方法时返回元素,所有不需要考虑内存的问题。

迭代器应用场景

数列的数据规模巨大 数列有规律,但是不能使用列表推导式描述

生成器

生成器是一种高级迭代器,使得需要返回一系列元素的函数所需的代码更加的简单和高效(不像创建迭代器代码那般冗长)

生成器函数

生成器函数基于yield指令,可以暂停一个函数并返回中间结果。当需要一个将返回一个序列或在循环中执行的函数时,就可以使用生成器,因为当这些元素被传递到另一个函数中进行后续处理时,一次返回一个元素可以有效的提升整体性能。 常见的应用场景是使用生成器生成数据流缓冲区

生成器表达式

生成式表达式是一种实现生成器的便捷方式,将列表推导式的中括号替换为圆括号。 和列表推导式的区别:列表生成式可以直接创建一个表,但是生成器表达式是一种边循环边计算,使得列表的元素可以在循环过程中一个个的推算出来,不需要创建完整的列表,从而节省了大量的空间。

g = (x*x for x in range(10))

总结:生成器是一种高级迭代器,生成器的优点是延迟计算,一次返回一个结果,这样非常适用于大数据量的计算。但是,使用生成器必须要注意的一点是:生成器只能遍历一次。

Lambda 表达式(匿名函数)

Lambda表达式可以省去定义函数的过程,让代码更加的简洁,适用于简单函数,编写处理更大业务的函数需要使用def定义 lambda表达式常用搭配map(), reduce(), filter() 函数使用 * map():map函数接受两个参数,一个是函数,一个是序列,其中函数可以接收一个或者多个参数。map将传入的函数依次作用于序列中的每一个元素,将结果作为新的列表返回。# 将一个列表中的数字转换为字符串map(str, [1, 2, 3, 4, 5, 6]) * reduce():函数接收两个参数,一个是函数,另一个是序列,但是,函数必须接收两个参数reduce把结果继续和序列的下一个元素做累积计算,其效果就是reduce(f, [x1, x2l x3, x4]) = f(f(f(x1, x2),x3),x4) * filter():该函数用于筛选,将传入的函数,依次作用于每个元素,然后根据函数的返回值是True还是False,决定是留下还是丢弃该元素

装饰器

装饰器本质是一个Python函数,它可以让其它函数在没有任何代码变动的情况下增加额外功能。有了装饰器,我们可以抽离出大量和函数功能本身无关的雷同代码并继续重用。经常用于具有切面需求的场景:包括插入日志,性能测试,事物处理,缓存和权限校验等。 场景:计算一个函数的执行时间 一种方法就是定义一个函数,用来专门计算函数的运行时间,然后运行时间计算完成之后再处理真正的业务代码,代码如下:

import timedef get_time(func):
      startTime = time.time()
      func()
      endTime = time.time()
      processTime = (endTime - startTime) * 1000
      print “The function timing is %d ms” %processTimedef myfunc():
      print “start func”
      time.sleep(0.8)
      print “end func”get_time(myfunc)myfunc()

  但是这段代码的逻辑破坏了原有的代码逻辑,就是对所有func函数的调用都需要使用get_time(func)来实现。 那么,有没有更好的展示方式呢?当然有,那就是装饰器。 编写简单的装饰器 结合上述实例,编写装饰器:

def get_time(func):
        def wrapper():
                startTime = time.time()
                func()
                endTime = time.time()
                processTime = (endTime - startTime) * 1000
                print “The function timing is %f ms” %processTime
        return wrapperprint “myfunc is:”, myfunc.__name__myfunc = get_time(myfunc)print “myfunc is:”, myfunc.__name__myfunc()

  这样,一个简单的完整的装饰器就实现了,可以看到,装饰器并没有影响函数的执行逻辑和调用。在Python中,可以使用“@”语法糖来精简装饰器的代码,将上例更改为:

@get_timedef myfunc():
        print “start func”
        time.sleep(0.8)
        print “end func”print “myfunc is: “, myfunc.__name__myfunc()

装饰器的调用顺序 装饰器可以叠加使用,若多个装饰器同时装饰一个函数,那么装饰器的调用顺序和@语法糖的声明顺序相反,也就是:

@decorator1@decorator2def func():
        pass等效于func = decorator1(decorator2(func()))

被装饰的函数带参数 上述实例中,myfunc()是没有参数的,那如果添加参数的话,装饰器改如何编写呢?

def get_time3(func):
        def wrapper(*args, **kwargs):
                startTime = time.time()
                func(*args, **kwargs)
                endTime = time.time()
                processTime = (endTime - startTime) * 1000
                print “The function timing is %f ms” %processTime
        return wrapper

@get_time3

def myfunc2(a):
print “start func”
        print a
        time.sleep(0.8)
        print “end func”a = “test”myfunc2(a)

带参数的装饰器 装饰器有很大的灵活性,它本身支持参数,例如在上述实例中,@get_time装饰器唯一的参数就是执行业务的函数,当然也可以在装饰器中添加参数,加以逻辑判断。 内置装饰器 Python中,常见的类装饰器包括:@staticmathod、@classmethod、@property * @staticmethod:类的静态方法,跟成员方法的区别是没有self参数,并且可以在累不进行实例化的情况下调用 * @classmethod:跟成员方法的区别是接收的第一个参数不是self,而是cls(当前累的具体类型) * @property:表示可以直接通过类实例直接访问的信息。

(0)

相关推荐

  • Python基础篇--迭代器,生成器和装饰器

    迭代 遵循迭代器协议时,需要Python迭代器对象支持两种方法. __iter__返回迭代器对象本身.这用于for 和in语句. __next__方法从迭代器返回下一个值.如果没有其他项目要返回,则应 ...

  • [书籍精读]《你不知道的JavaScript(下卷)》精读笔记分享

    写在前面 书籍介绍:JavaScript这门语言简单易用,很容易上手,但其语言机制复杂微妙,即使是经验丰富的JavaScript开发人员,如果没有认真学习的话也无法真正理解.本套书直面当前JavaSc ...

  • 零基础学Python:列表推导式及深浅拷贝

    列表推导式 Python里面有个很棒的语法糖(syntactic sugar),它就是 list comprehension ,有人把它翻译成"列表推导式",也有人翻译成" ...

  • 列表推导式:简洁高效更具 Python 风格的列表创建方法

    我们在<Python 中的列表和元组>中已经详细介绍了列表(list)的基本特性和使用方法,本文将着重介绍一种 Python 中用于创建 list 的简洁高效的语法形式:列表推导式. Py ...

  • 编程语言python经典有序序列的list列表推导式实践运用

    file [阅读全文] 生成一个数据列表 # 初始化一个列表 list_1 = [] # 使用循环生成一个列表数据 for val in range(0,20,1): # 加入集合 list_1.ap ...

  • 优雅简洁的列表推导式

    优雅的列表推导式 最近比较累,给自己放了很长的假.使用廖雪峰网站学习时一开始学过列表推导式这方面的知识,但不知道有什么用,也没觉得好看简洁.但接触的多了,用的多了之后,发现推导式确实好用. 使用推导式 ...

  • Python 炫技操作:推导式的五种写法

    作者:写代码的明哥 来源:Python编程时光 推导式(英文名:comprehensions),也叫解析式,是Python的一种独有特性. 推导式是可以从一个数据序列构建另一个新的数据序列的结构体. ...

  • 奇技淫巧,还是正统功夫? - Python推导式最全用法

    作者:麦叔 源自:麦叔编程 1 Pythonic - 很Python 写一段代码生成1到100之间的数字的平方的列表,答案是: 1,4,9,16... 如果你这样写,你就不Pythonic了: num ...

  • 第 61 天:Python Requests 库高级用法

    上一篇我们介绍了 Requests 库的基本用法,学会之后大家就可以应付一般的请求了.这一篇我们接着介绍 Requests 的高级用法,以便应付一些棘手的问题. 会话维持 在 requests 中,直 ...

  • Python的 5 种高级用法,效率提升没毛病!

    任何编程语言的高级特征通常都是通过大量的使用经验才发现的.比如你在编写一个复杂的项目,并在 stackoverflow 上寻找某个问题的答案.然后你突然发现了一个非常优雅的解决方案,它使用了你从不知道 ...

  • Python进阶:切片的误区与高级用法

    众所周知,我们可以通过索引值(或称下标)来查找序列类型(如字符串.列表.元组-)中的单个元素,那么,如果要获取一个索引区间的元素该怎么办呢? 切片(slice)就是一种截取索引片段的技术,借助切片技术 ...