Python高级用法总结


Posted in Python onMay 26, 2018

列表推导(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, seq[i])

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

def getitem(index, element):
  return '%d: %s' % (index, element)

array = ['I', 'love', 'Python']
arrayIndex = [getitem(index, element) for index, element in enumerate(array)]

据说这种写法更加的Pythonic。

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

迭代器和生成器

迭代器(Iterator)

这里的迭代可以指for循环,在Python中,对于像list,dict和文件等而言,都可以使用for循环,但是它们并不是迭代器,它们属于可迭代对象。

什么可迭代对象

最简单的解释:可以使用for...in...语句进行循环的对象,就是可迭代对象(Iterable),可以使用isinstance()方法进行判断。

from collections import Iterable 
type = 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表达式纯粹是为了编写简单函数而设计,起到了一个函数速写的作用,使得简单函数可以更加简洁的表示。

lambda和def的区别

lambda表达式可以省去定义函数的过程,让代码更加的简洁,适用于简单函数,编写处理更大业务的函数需要使用def定义。
lambda表达式常搭配map(), reduce(), filter()函数使用

  • map(): map函数接受两个参数,一个是函数,一个是序列,其中,函数可以接收一个或者多个参数。map将传入的函数依次作用于序列中的每个元素,将结果作为新的列表返回。
    #将一个列表中的数字转换为字符串 map(str, [1,2,3,4,5,6])

  • reduce():函数接收两个参数,一个是函数,另一个是序列,但是,函数必须接收两个参数reduce把结果继续和序列的下一个元素做累积计算,其效果就是reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)。

  • filter():该函数用于筛选,将传入的函数,依次作用于每个元素,然后根据函数的返回值是True还是False,决定是留下还是丢弃该元素。

装饰器

装饰器本质是一个Python函数,它可以让其它函数在没有任何代码变动的情况下增加额外功能。有了装饰器,我们可以抽离出大量和函数功能本身无关的雷同代码并继续重用。经常用于具有切面需求的场景:包括插入日志、性能测试、事务处理、缓存和权限校验等。

那么为什么要引入装饰器呢?

场景:计算一个函数的执行时间。

一种方法就是定义一个函数,用来专门计算函数的运行时间,然后运行时间计算完成之后再处理真正的业务代码,代码如下:

import time 

def get_time(func):
  startTime = time.time()
  func()
  endTime = time.time()
  processTime = (endTime - startTime) * 1000
  print "The function timing is %f ms" %processTime

def 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 wrapper
  
print "myfunc is:", myfunc.__name__
myfunc = get_time(myfunc)
print "myfunc is: ", myfunc.__name__
myfunc()

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

@ get_time
def myfunc():
  print "start func"
  time.sleep(0.8)
  print "end func"

print "myfunc is: ", myfunc.__name__
myfunc()

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

@decorator1
@decorator2
def 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:表示可以直接通过类实例直接访问的信息。

以上,是本次整理的Python高级用法,本文将持续更新。

Python 相关文章推荐
python批量修改文件名的实现代码
Sep 01 Python
详解详解Python中writelines()方法的使用
May 25 Python
Python 实现数据库更新脚本的生成方法
Jul 09 Python
Python学习入门之区块链详解
Jul 25 Python
Python之读取TXT文件的方法小结
Apr 27 Python
python中使用iterrows()对dataframe进行遍历的实例
Jun 09 Python
pytorch 改变tensor尺寸的实现
Jan 03 Python
Python多线程通信queue队列用法实例分析
Mar 24 Python
python实现最速下降法
Mar 24 Python
解决reload(sys)后print失效的问题
Apr 25 Python
Python CSS选择器爬取京东网商品信息过程解析
Jun 01 Python
keras训练浅层卷积网络并保存和加载模型实例
Jul 02 Python
关于Python的一些学习总结
May 25 #Python
windows下python和pip安装教程
May 25 #Python
python2.7实现爬虫网页数据
May 25 #Python
python sys.argv[]用法实例详解
May 25 #Python
python切片及sys.argv[]用法详解
May 25 #Python
windows下python安装pip图文教程
May 25 #Python
python3.6使用pymysql连接Mysql数据库
May 25 #Python
You might like
使用symfony命令创建项目的方法
2016/03/17 PHP
使用jQuery简化Ajax开发 Ajax开发入门
2009/10/14 Javascript
Javascript 中文字符串处理额外注意事项
2009/11/15 Javascript
在jquery中处理带有命名空间的XML数据
2011/06/13 Javascript
jquery中的过滤操作详细解析
2013/12/02 Javascript
简单的邮箱登陆的提示效果类似于yahoo邮箱
2014/02/26 Javascript
使用jQuery设置disabled属性与移除disabled属性
2014/08/21 Javascript
Javascript验证用户输入URL地址是否为空及格式是否正确
2014/10/09 Javascript
asp.net+js实现金额格式化
2015/02/27 Javascript
动态生成的DOM不会触发onclick事件的原因及解决方法
2016/08/06 Javascript
原生javascript实现的ajax异步封装功能示例
2016/11/03 Javascript
bootstrap侧边栏圆点导航
2017/01/11 Javascript
原生js实现对Ajax的封装(仿jquery)
2017/01/22 Javascript
Java中int与integer的区别(基本数据类型与引用数据类型)
2017/02/19 Javascript
React利用插件和不用插件实现双向绑定的方法详解
2017/07/03 Javascript
Vue学习笔记进阶篇之过渡状态详解
2017/07/14 Javascript
JavaScript自执行函数和jQuery扩展方法详解
2017/10/27 jQuery
vue基于mint-ui实现城市选择三级联动
2020/06/30 Javascript
微信小程序实现倒计时补零功能
2018/07/09 Javascript
vue新建项目并配置标准路由过程解析
2019/12/09 Javascript
Python中函数的用法实例教程
2014/09/08 Python
python字符串替换的2种方法
2014/11/30 Python
Python数据分析之真实IP请求Pandas详解
2016/11/18 Python
PyCharm设置每行最大长度限制的方法
2019/01/16 Python
8段用于数据清洗Python代码(小结)
2019/10/31 Python
Python3如何判断三角形的类型
2020/04/12 Python
什么是python的id函数
2020/06/11 Python
python小技巧——将变量保存在本地及读取
2020/11/13 Python
新西兰演唱会和体育门票网站:Ticketmaster新西兰
2017/10/07 全球购物
新闻学专业应届生求职信
2013/11/08 职场文书
上学迟到的检讨书
2014/01/11 职场文书
八项规定自查自纠报告及整改措施
2014/10/26 职场文书
破坏寝室公物检讨书
2014/11/17 职场文书
Python - 10行代码集2000张美女图
2021/05/23 Python
Win7/8.1用户可以免费升级到Windows 11系统吗?
2021/11/21 数码科技
Go语言怎么使用变长参数函数
2022/07/15 Golang