Python高阶用法总结

目录

  • 1. lambda匿名函数

    • 1.1 函数式编程
    • 1.2 应用在闭包
  • 2. 列表解析式
  • 3. enumerate内建函数
  • 4. 迭代器与生成器
    • 4.1 迭代器
    • 4.3 生成器
  • 5. 装饰器

前言: 接触python有一段时间了,从开始的看菜鸟的python教程,看了一些视频,一些书。很多人感觉python很简单,确实相比其他语言,python可能稍微简单一点,但是不能说只学了python基础语法就说自己python水平可以了。最近在阅读YOLOv3的pytorch版本源码,就遇到很多瓶颈,很多是与python相关的。所以这篇进行总结一下,收集一下所有的问题,更深入理解python高阶用法,并且尽量每个都附上例子,做一个认真的coder,bloger。

1. lambda匿名函数

lambda匿名函数在一些工程项目中经常出现,理解该用法是读懂项目的前提。如:

lf = lambda x: 1 - 10 ** (hyp['lrf'] * (1 - x / epochs)) 

匿名函数就是没有定义函数的名称,用来实现简单的功能。

语法结构:lambda param_list: expression

param_list 就是参数列表,相当于函数的参数

expression 就是表达式,相当于函数体,用一行进行表示

举个简单的例子:

>>> func=lambda x, y: x+y
>>> func(3,4)
7

应用场景:

1.1 函数式编程

python提供了很多函数式编程特性,如map, reduce, filter, sorted等内置函数,都支持函数作为参数。

  • map会根据提供的函数对指定序列做映射。

    • map(function, iterable, ...)
    •   >>> func2=lambda x: x**x
        >>> L=[1,2,3]
        >>> map(func2, L)
        <map object at 0x00000218C07F0080>
        >>> list(map(func2, L)) # 注意要显示内容需要转为list类型,因为py3中返回的是迭代器对象
        [1, 4, 27]
        >>>
    • 其中function可以使lambda函数对象,也可以是str等类型
    •   >>> L=[1,2,3,4]
        >>> list(map(str, L))
        ['1', '2', '3', '4']
        >>> list(map(float, L))
        [1.0, 2.0, 3.0, 4.0]
  • reduce 函数会对参数序列中元素进行累积。
    • 语法:reduce(function, iterable[, initializer])
    •   >>> reduce(lambda x, y: x+y, [1,2,3,4,5])  # 使用 lambda 匿名函数
        15
    • 注意python3使用前要加上:from functools import reduce , reduce函数在python3中被移除,放入了functools模块。
  • filter内置函数用于过滤序列,过滤掉不符合条件的元素,返回由符合条件元素组成的新列表。
    •   filter(function, iterable)
    •   >>> filter(lambda x: x % 2 == 0, [1,2,3,4,5,6,7,8,9,10])
        <filter object at 0x00000218C07F0080>
        >>> list(filter(lambda x: x % 2 == 0, [1,2,3,4,5,6,7,8,9,10]))
        [2, 4, 6, 8, 10]
        >>>
    • 这里function智能返回true or false, 将满足true的放入最终列表。
  • sorted函数对所有可迭代的对象进行排序操作。
    • sorted(iterable, key=None, reverse=False)
    •   >>> sorted([[3,4],[2,1],[5,3],[7,4],[9,0]], key=lambda x:x[0])
        [[2, 1], [3, 4], [5, 3], [7, 4], [9, 0]]

1.2 应用在闭包

def get_y(a,b):
     return lambda x:ax+b
y1 = get_y(1,1)
y1(1) # 结果为2

用常规函数实现闭包,如下:

def get_y(a,b):
    def func(x):
        return ax+b
    return func
y1 = get_y(1,1)
y1(1) # 结果为2

例子转载自:https://www.cnblogs.com/hf8051/p/8085424.html

2. 列表解析式

列表解析式是Python内置的非常简单强大的可以用来创建list的生成式。在深度学习项目中也可以经常看到这种用法。

(1) 语法1:[表达式 for 变量 in 列表],表示把得到的每一个变量值都放到 for 前面的表达式中计算 ,然后生成一个列表

(2) 语法2:[表达式 for 变量 in 列表 if 条件],如果加上 if 判断,则表示把每一个变量值进行判断,如果判断正确再交给表达式进行计算,然后生成一个列表

举例:

>>> items=[1,2,3,4,5,6,7]
>>> [item*2 for item in items]
[2, 4, 6, 8, 10, 12, 14]
>>> [item*2 for item in items if item % 2 == 0]
[4, 8, 12]

使用列表解析式的写法更加简短,除此之外,因为是Python内置的用法,底层使用C语言实现,相较于编写Python代码而言,运行速度更快。

3. enumerate内建函数

对于一个列表,既要遍历索引又要遍历元素。

>>> days=['mon','tus','wed','ths','fri','sat','sun']
>>> for i,day in enumerate(days):
...     print(i,day)
...
0 mon
1 tus
2 wed
3 ths
4 fri
5 sat
6 sun
>>> for i,day in enumerate(days, start=1):
...     print(i,day)
...
1 mon
2 tus
3 wed
4 ths
5 fri
6 sat
7 sun
>>>

4. 迭代器与生成器

有时候项目会使用到这种语法,如果不了解这两种用法,可能很难读懂代码,可能会直接懵B o((⊙﹏⊙))o。下面分别看看这两个的用法:

4.1 迭代器

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

>>> L=[1,2,3,4,5]
>>> lst = iter(L)
>>> type(lst)
<class 'list_iterator'>
>>> L1=(1,2,3,4,5)
>>> lst1 = iter(L1)
>>> type(lst1)
<class 'tuple_iterator'>
>>> next(lst)
1
>>> next(lst1)
1
>>>

迭代器优势: 所有的元素不是一次性加载的,在调用next方法才会返回,不需要考虑内存问题。next()只能往后进行访问。

迭代器应用场景:

  1. list规模过大,出于对内存的考虑使用迭代器。
  2. 有规律,但是不能使用列表推导式描述

迭代器的创建:

  1. __iter__() 方法返回一个特殊的迭代器对象, 这个迭代器对象实现了 next() 方法并通过 StopIteration 异常标识迭代的完成。
  2. __next__() 方法(Python 2 里是 next())会返回下一个迭代器对象。
class MyNumbers:
  def __iter__(self):
    self.a = 1
    return self

  def __next__(self):
    x = self.a
    self.a += 1
    return x

myclass = MyNumbers()
myiter = iter(myclass)

print(next(myiter))
print(next(myiter))

例子来自菜鸟教程:https://www.runoob.com/python3/python3-iterator-generator.html

4.3 生成器

生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。

使用了yield的函数被称为生成器。

在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值, 并在下一次执行 next() 方法时从当前位置继续运行。(之前也遇见过yolo的代码中使用了这种用法,需要仔细理解并掌握)

#!/usr/bin/python3

import sys

def fibonacci(n): # 生成器函数 - 斐波那契
    a, b, counter = 0, 1, 0
    while True:
        if (counter > n):
            return
        yield a
        a, b = b, a + b
        counter += 1
f = fibonacci(10) # f 是一个迭代器,由生成器返回生成

while True:
    try:
        print (next(f), end=" ")
    except StopIteration:
        sys.exit()

例子来自菜鸟教程:https://www.runoob.com/python3/python3-iterator-generator.html

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

5. 装饰器

装饰器本质是一个python函数,如果学过flask就知道,里边装饰器是必须的,经常用到。

装饰器的作用:抽离大量和函数功能本身无关的代码进行重用

一个简单的装饰器,用于计数,由于对不同的函数运行时间进行计数的需要,所以要对时间计数这部分进行处理。

def get_time(func):
    def wrapper():
        startTime = time.time()
        func()
        endTime = time.time()
        print("spend %f" % (endTime-startTime))
    return wrapper
myFunction = get_time(myFunction)
    

精简一下,使用@语法来进行精简:

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)

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

if __name__ == "__main__":
    myfunc

output:

start
end
The function timing is 800.058126 ms

理解为:get_time(myfun()) ,将myfunc()函数包裹

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

@decorator1
@decorator2
def func():
    pass

等效于:

func = decorator1(decorator2(func()))

内置装饰器

Python中,常见的类装饰器包括:@staticmathod、@classmethod和@property

  • @staticmethod:类的静态方法,跟成员方法的区别是没有self参数,并且可以在类不进行实例化的情况下调用。
  • @classmethod:跟成员方法的区别是接收的第一个参数不是self,而是cls(当前类的具体类型)
  • @property:表示可以直接通过类实例直接访问的信息。

了解更多请看:https://www.jianshu.com/p/ee82b941772a

原文地址:https://www.cnblogs.com/pprp/p/11722730.html

时间: 2024-10-27 18:03:25

Python高阶用法总结的相关文章

Python高阶函数_map/reduce/filter函数

本篇将开始介绍python高阶函数map/reduce/filter的用法,更多内容请参考:Python学习指南 map/reduce Python内建了map()和reduce()函数. 如果你读过Google的那篇大名鼎鼎的论文"MapReduce: Simplified Data Processing on Large Clusters",你就能大概明白map/reduce的概念. 我们先看map.map()函数接收两个参数,一个是函数,一个是序列,map将传入的函数依次作用到序

python高阶函数的使用

目录 python高阶函数的使用 1.map 2.reduce 3.filter 4.sorted 5.小结 python高阶函数的使用 1.map Python内建了map()函数,map()函数接受两个参数,一个是函数,一个是Iterable,map将传入的函数依次作用到序列的每一个元素上,并把结果作为新的Iterator返回. 举例说明,比如我们有一个函数f(x)=x*2,要把这个函数作用在一个list[1, 2, 3, 4, 5, 6, 7, 8, 9]上,就可以用map()实现. >>

python 高阶函数详解。

1,概念: Iterable 和 IteratorIterable 表示该变量可以被 for in 进行迭代.Iterator 表示该变量可以被 next(o)进行迭代(上一个表示有限迭代,下一个表示一个惰性的迭代概念,可以无限迭代.)一般的Iterable 的变量有:L=[{},[],(1,),{3:4},{3,4}]for x in L:print(isinstance(x,Iterable))print(isinstance(x,Iterator)) truefalse 可见,基础变量Li

python 高阶函数用法

1.map()函数 map()函数接收两个参数,一个是函数,一个是Iterable,map将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator返回. def f(x): return x * x L = map(f,[1,2,3,4,5]) list(L) [1,4,9,16,25] 2.reduce()函数 reduce把一个函数作用在一个序列[x1, x2, x3, ...]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算, 其效果就是:re

Python高阶函数-闭包

高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回. 在这里我们首先回忆一下python代码运行的时候遇到函数是怎么做的. 从python解释器开始执行之后,就在内存中开辟了一个空间 每当遇到一个变量的时候,就把变量名和值之间的对应关系记录下来. 但是当遇到函数定义的时候解释器只是象征性的将函数名读入内存,表示知道这个函数的存在了,至于函数内部的变量和逻辑解释器根本不关心. 等执行到函数调用的时候,python解释器会再开辟一块内存来存储这个函数里的内容,这个时候,才关注函数里面有哪

Python: 高阶函数与lambda表达式

缘由: python语法简单一看就会,但用在实处,想因为少于实战,总感觉有些捉襟. 翻阅跟踪youtube_dl源码,看到filter()函数用法,及其中lambda表达式,感觉好有意思,就补下课,记录所思. 1. 高阶函数 所谓高阶函数,即是能接受函数做参数的函数.函数做参,与c#委托.c++函数指针.Delphi事件有类似之处 比如: def my_func(f, *args): f(args) def my_print(s): print ', '.join(s) my_func(my_p

Python 高阶函数【转】

函数是Python内建支持的一种封装,我们通过把大段代码拆成函数,通过一层一层的函数调用,就可以把复杂任务分解成简单的任务,这种分解可以称之为面向过程的程序设计.函数就是面向过程的程序设计的基本单元. 而函数式编程(请注意多了一个"式"字)--Functional Programming,虽然也可以归结到面向过程的程序设计,但其思想更接近数学计算. 我们首先要搞明白计算机(Computer)和计算(Compute)的概念. 在计算机的层次上,CPU执行的是加减乘除的指令代码,以及各种条

python高阶函数

什么是高阶函数?根据例子一步步来 变量可以指向函数 以python内置的求绝对值的函数abs为例,我们可以有下面几种调用方法 >>> abs(-10) 10 但是如果只写abs呢? >>> abs <built-in function abs> abs(-10)是函数的调用,abs是函数本身 我们知道结果可以赋值给变量,函数是否可以呢? >>> x=abs(-10) >>> x 10 y=abs >>>

Python高阶函数与函数装饰器-day4

上节回顾 高阶函数 闭包函数 函数装饰器 模块导入 一.上节回顾 Python2与Python3字符编码问题,不管你是初学者还是已经对Python的项目了如指掌了,都会犯一些编码上面的错误.我在这里简单归纳Python3和Python2各自的区别. 首先是Python3-->代码文件都是用utf-8来解释的.将代码和文件读到内存中就变成了Unicode,这也就是为什么Python只有encode没有decode了,因为内存中都将字符编码变成了Unicode,而Unicode是万国码,可以"