Python超能力:高级技巧让你的代码飞起来

文章一览

  • 前言
  • 一、with
  • 1.1 基本用法
  • 1.2 示例
  • 自定义上下文管理器
  • 二、条件表达式
  • 三、列表式推导式
  • 与 zip 结合
  • 四、map() 函数(内置函数)
  • map用于数据清洗
  • 1. 数据清洗:字母大小写规范
  • 2. filter() 函数
  • 五、匿名函数 lambda
  • 5.1 lambda的参数(argument_list)和表达式
  • 5.2 lambda 函数与其它函数搭配使用
  • 5.3 匿名函数的优势
  • 前言

    在当今这个技术日新月异的时代,Python已经成为全球开发者的首选语言之一,它以其简洁、高效和强大的功能闻名于世。然而,Python的真正魅力远不止于此——它隐藏着许多高级技巧,这些技巧能够极大地提升你的编程能力,让你的代码更加优雅、高效和强大。这些高级技巧是Python高手的秘密武器,它们能够解决复杂的问题,优化性能,甚至改变你对编程的看法。

    现在,让我们一起揭开Python高级技巧的神秘面纱,探索那些让代码更智能、更灵活的高级特性。无论你是Python新手还是老手,这些高级技巧都将为你打开新世界的大门,让你的编程之路更加宽广。

    准备好了吗?让我们一起踏上这段激动人心的Python高级技巧之旅,解锁编程的新高度,成为真正的Python大师!

    一、with

    在Python中,with语句是一种上下文管理协议,用于包装代码执行前后的初始化与清理工作。它使得代码更加简洁,易于阅读,并且能够自动管理资源,比如文件操作、线程锁的获取与释放等。with语句通过__enter__()__exit__()这两个方法来实现资源的封装管理。

    1.1 基本用法

    with expression as variable:
        # 在这个代码块中,可以使用variable
        # 执行一些操作
        # ...
    # 当离开这个代码块时,会自动执行一些清理工作
    

    这里的expression必须是一个上下文管理器(context manager)对象,它必须实现__enter__()__exit__()方法。__enter__()方法在进入代码块之前被调用,其返回值(如果有的话)会被赋值给as子句中的variable__exit__()方法在代码块执行完毕后被调用,无论是正常结束还是由于异常而结束。

    1.2 示例

    例1:文件操作

    使用with语句进行文件操作是一个很好的例子,因为它可以自动管理文件的打开和关闭:

    with open('example.txt', 'r') as file:
        content = file.read()
        print(content)
    # 文件在这里自动关闭
    

    在这个例子中,open()函数返回一个文件对象,这个对象是一个上下文管理器。当进入with语句的代码块时,__enter__()方法被调用,返回的文件对象被赋值给file变量。当离开代码块时,__exit__()方法被调用,文件被自动关闭。

    自定义上下文管理器

    也可以通过定义一个类,并实现__enter__()__exit__()方法来创建自己的上下文管理器:

    class MyContextManager:
        def __enter__(self):
            print("Entering")
            return self  # 可以返回任何对象,或者None
    
        def __exit__(self, exc_type, exc_val, exc_tb):
            print("Exiting")
            # 如果需要,可以在这里处理异常
            # 如果处理了异常,应该返回True
            # 否则,返回False(或者省略return,默认为False)
            return False
    
    with MyContextManager() as cm:
        print("Inside the context manager")
    # 输出:
    # Entering
    # Inside the context manager
    # Exiting
    

    ​ 在这个例子中,MyContextManager类定义了一个简单的上下文管理器,它在进入和离开with语句的代码块时分别打印消息。注意,__exit__()方法接收三个参数,分别用于异常处理:exc_type是异常类型,exc_val是异常值,exc_tb是异常跟踪信息(traceback)。如果__exit__()方法返回True,则异常会被忽略(即被处理)。如果返回False(或没有返回值,默认为False),则异常会被正常抛出。

    二、条件表达式

    if x > 0:
        y = x*2
    else:
        y = x
        
    # 使用条件表达式
    y = x*2 if x > 0 else x
    

    简单的条件表达式可以直接写到一行上,而且不用冒号了“:”

    三、列表式推导式

    列表推导式 是Python基础,也是最受欢迎的 Python 特性之一

    >>> a = []
    >>> for i in range(0,10):
    >>>     a.append(i)
    >>> print (a)
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    # 使用列表推导式
    >>> a = [i for i in range(0,10)]
    >>> print (a)
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    

    本质上可以把列表推导式理解成一种集合了 变换 和 筛选 功能的 函数,通过这个函数把一个列表转换成另一个列表

    注意:是另一个新列表,原列表保持不变

    形式1:[表达式 for 变量 in 列表(或range)]

    形式2:[表达式 for 变量 in 列表 if 条件]

    格式 1:[expression for item in iterable]

    lis = []
    for i in range(100):
        lis.append(i)
    print (lis)
    # 使用列表推导式
    lis = [i for i in range(100)]
    print (lis)
    

    格式 2[expression for item in iterable if 条件]

    lis = []
    for i in range(100):
        if i % 2 == 0:
            lis.append(i)
    print (lis)
    # 使用列表推导式
    lis = [i for i in range(100) if i % 2 == 0]
    print (lis)
    
    a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    b = [x ** 3 for x in a if x % 2 == 0]
    print ('a :',a)
    print ('b :',b)
    

    从结果上可以看出:如果有筛选条件是先筛选再变换,即先筛掉不满足条件的元素,再进行变换运算。

    也可以同时加多个筛选条件,如对大于 5 的且是偶数的元素进行立方运算

    >>> a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    >>> b = [x ** 3 for x in a if x % 2 == 0 and  x > 5]
    >>> print (b)
    [216, 512, 1000]
    

    如对大于 5 的或者是偶数的元素进行立方运算

    >>> a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    >>> b = [x ** 3 for x in a if (x % 2 == 0 or x > 5)]
    >>> print (b)
    [8, 64, 216, 343, 512, 729, 1000]
    

    与 zip 结合

    zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个列表组,然后返回由这些列表组组成的列表

    a,b 两个列表中相对应的值组合起来,形成一个新列表。例如包含x 坐标的列表与 y 坐标的列表形成相对应的点坐标 [x, y] 列表

    >>> a = [1, 2, 3, 4, 5]
    >>> b = [6, 7, 8, 9, 10]
    >>> c = [[x, y] for x, y in zip(a, b)]
    >>> print(c)
    [[1, 6], [2, 7], [3, 8], [4, 9], [5, 10]]
    

    四、map() 函数(内置函数)

    map(function, iterable,…)

    参数function传的是一个函数名,可以是python内置的,也可以是自定义的

    参数iterable传的是一个可以迭代的对象,如 列表,元组,字符串

    map() 接收一个函数 function 和一个 iterable ,并通过把函数 f 依次作用在 iterable 的每个元素上,得到一个新的 iterable 并返回

    给定一列数据,使该列数据中每个元素乘 2

    lis = [16,15,13,11,18,17,12,14]
    print (lis)
    i = 0
    for j in lis:
        lis[i] = j*2
        i = i + 1
    print (lis)
    

    用 map() 函数如何做呢?

    def f(x):
        return x*2
    lis = [16,15,13,11,18,17,12,14]
    lis1 = map(f, lis)
    print (lis1)
    

    注意:map 函数返回时返回的是一个地址

    如果要输出值,必须在外层加上list()

    def f(x):
        return x*2
    lis = [16,15,13,11,18,17,12,14]
    lis1 = map(f, lis)
    print (list(lis1))
    

    获取两个列表对应位置上的最小值

    >>> l1 = [1,3,7,10]
    >>> l2 = [2,4,6,9]
    >>> mins = map (min,l1,l2)
    >>> print(list(mins))
    [1, 3, 6, 9]
    

    获取多输入整数或浮点数

    m,n = map(int,input().split(','))
    lis = [*map(int, input().split(','))]
    lis = [*map(float,input().split(','))]
    

    map用于数据清洗

    什么是数据清洗?

    ​ 一般拿到初始数据后是不能直接用到模型的。比如字符串有些是大写,有些是小写,有些是首字母大写,现在需要处理成统一的格式(首字母大写),这个过程就是数据清洗

    1. 数据清洗:字母大小写规范
    'adam', 'LISA', 'barT', 'PYTHON'
    >>> def format_name(s):
    >>>     s=s[0].upper()+s[1:].lower()
    >>>     return s
    >>> s = ['adam', 'LISA', 'barT', 'PYTHON']
    >>> s = map(format_name, s)
    >>> print (list(s))
    ['Adam', 'Lisa', 'Bart', 'Python']
    
    2. filter() 函数

    filter() 函数是 Python 中常用的内置函数,它主要用来根据特定条件过滤迭代器中不符合条件的元素,需要用list函数进行转换,才能得到符合的条件元素组成的新列表

    filter(function, iterable,…)

    lis = [4,9,3,14,7,10,6,1]
    def odd(x):
        if x % 2 == 1:
            return x 
    newlis = list(filter(odd,lis))
    print(newlis)
    

    五、匿名函数 lambda

    lambda 函数,或称为匿名函数,是一个没有函数名的简单函数。语法如下:

    lambda arguments: expression

    lambda 关键字可以用来创建一个 lambda 函数,紧跟其后的是参数列表用冒号分割开的单个表达式

    参数(arguments) 和 表达式(expression)由用户自定义

    5.1 lambda的参数(argument_list)和表达式

    lambda arguments: expression

    匿名函数的 arguments 和普通函数参数一样,可以有非常多的形式

  • expression中出现的参数需要在 argument 中有定义,并且表达式只能是单行的
  • lambda 函数输入是传入到 argument的值,输出是根据 expression 计算得到的值

    例如,lambda x: 2 * x 是将任何输入的数乘 2,而 lambda x, y: x+y 是计算两个数字的和。语法十分直截了当

    y = lambda x: 2 * x
    print(y(6))
    
    def f(x,y):
        return x+y
    f (10,20)
    
    # lambda 表达式
    f = lambda x,y: x+y
    print (f(10,20))
    

    简单说,lambda 函数用于定义简单的、能够在一行内表示的函数。特别提醒

  • 只能写一个表达式,表达式的结果就是返回值
  • 不用 return 语句
  • 与其他的使用常规 def 关键字创建的函数不同,lambda 函数没有名字

    5.2 lambda 函数与其它函数搭配使用

    lambda 函数经常和高阶函数一起使用,比如 map 或 filter

    l1 = [1,3,5,7,9]
    l2 = [2,4,6,8,10]
    result = map (lambda x,y: x * 2 + y, l1,l2)
    print (list (result))
    
    >>> m = lambda *args : sum(args)
    >>> print (m(3,4,5,6))
    18
    
    >>> lis = [-10, 28, 9, -5, 30, 5]
    >>> new_lis = list(filter(lambda x:x>0, lis))
    >>> print(new_lis)
    [28, 9, 30, 5]
    

    5.3 匿名函数的优势

    为什么经常把 for 循环和序列(可迭代)类型数据联合使用?

    ​ 因为数据在容器里存放,要处理数据就需要对容器里的数据进行遍历

    ​ 用 for 循环遍历十次百次千次,如果遍历百万千万次呢?for 循环效率低!能不用 for 循环就不用 。可以用匿名函数 lambda,简单的函数操作,返回值是 func 类型,在数据分析和清洗中结合 map() 大量会用到匿名函数。

    ​ 另外,有些函数如果只是临时一用,而且它的业务逻辑也很简单时,就没必要非给它取个名字不可!

    作者:KevinRay_

    物联沃分享整理
    物联沃-IOTWORD物联网 » Python超能力:高级技巧让你的代码飞起来

    发表回复