【Python】高级语法:推导式、迭代器、生成器、装饰器

news2024/11/24 13:54:13

原文作者:我辈李想
版权声明:文章原创,转载时请务必加上原文超链接、作者信息和本声明。


文章目录

  • 一、推导式
    • 1.列表推导式
    • 2.集合推导式
    • 3.字典推导式
  • 二、迭代器
  • 三、生成器
    • 1.yield 生成器
    • 2.元组生成器
    • 3.生成器中重要方法
  • 四、装饰器
    • 1.函数装饰器
    • 2.可传参函数装饰器
    • 3.类装饰器
    • 4.可传参的类装饰器


一、推导式

语法格式为:

new_set = {expression for item in iterable if condition}

其中,
new_set 是新生成的集合;
expression 是一个表达式,用于计算集合中元素的值;
item 是集合的元素;
iterable 是一个可迭代对象,如列表、元组、字符串等;
if 语句是可选的,用于筛选元素。

1.列表推导式

列表推导式是 Python 中常用的一种快速创建列表的方式。它可以通过一行代码来生成一个新的列表,而不需要繁琐的循环和条件语句。
下面是一个简单的示例,演示了如何使用列表推导式生成一个1到10的平方数列表:

squares = [x**2 for x in range(1, 11)]
print(type(squares))
print(squares)

输出结果

<class 'list'>
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

列表推导式也可以使用条件语句来过滤元素。下面是一个示例,演示了如何使用列表推导式生成1到10的平方数列表,但只包括偶数:

squares = [x**2 for x in range(1, 11) if x % 2 == 0]
print(type(squares))
print(squares)

输出结果

<class 'list'>
[4, 16, 36, 64, 100]

在上面的示例中,列表推导式使用for循环语句遍历1到10的整数,但只包括偶数,并使用x**2计算每个偶数的平方,然后将结果添加到新的列表中。

列表推导式的优点是可读性高,能够快速创建列表。但是,当可读性受到影响或数据处理较复杂时,建议使用传统的循环和条件语句

2.集合推导式

Python 集合推导式是用来生成集合的一种快捷方式,它类似于列表推导式。

new_set = {x**2 for x in range(1,6)}
print(type(new_set))
print(new_set)

输出结果

<class 'set'>
{1, 4, 9, 16, 25}

上面的例子是生成由 1 到 5 的平方组成的集合。

3.字典推导式

字典推导式的语法与列表推导式和集合推导式类似,但是需要使用花括号 {},可以加入条件表达式等来筛选元素,实现更加复杂的生成。

my_dict = {i: i ** 2 for i in range(1, 6)}
print(type(my_dict))
print(my_dict)

输出结果

<class 'dict'>
{1: 1, 2: 4, 3: 9, 4: 16, 5: 25}

在上面的例子中,我们使用了一个字典生成器,将 1 到 5 的整数作为字典的键,并将其平方作为值。

二、迭代器

在Python中,迭代器(Iterator)和可迭代对象(Iterable)是两个重要的概念。

可迭代对象是指实现了 iter 或者 getitem 方法的对象,例如列表、元组、集合、字典、字符串等。这些对象可以通过 for 循环进行迭代,或者使用 iter() 函数将其转换为迭代器。

迭代器是指实现了 iternext 方法的对象。__iter__方法返回迭代器对象本身,__next__方法返回数据集合中的下一个元素,如果没有下一个值,就抛出 StopIteration 异常。迭代器只能向前遍历一次,无法回到前面的位置。

示例:迭代对象转迭代器

my_list = [1, 2, 3]
iterator = iter(my_list)
print('my_list',type(my_list))
print('iterator',type(iterator))

输出结果

my_list <class 'list'>
iterator <class 'list_iterator'>

需要注意的是,虽然可迭代对象可以使用 iter() 函数转换为迭代器,但是迭代器本身也是可迭代对象。也就是说,迭代器可以在 for 循环中直接使用。

my_list = [1, 2, 3]
iterator = iter(my_list)
for item in iterator:
    print(item)

迭代器是一个可以遍历数据集合的对象,它的作用是提供一种统一的访问数据集合的方法,而不必关注数据的底层实现方式。

示例:创建一个迭代器

class MyIterator:
    def __iter__(self):
        self.a = 1
        return self

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

my_iter = MyIterator()
my_iter_iter = iter(my_iter)
print(type(my_iter_iter))

print(next(my_iter_iter))
print(next(my_iter_iter))
print(next(my_iter_iter))

输出

<class '__main__.MyIterator'>
1
2
3

三、生成器

生成器是一种特殊的迭代器,它可以动态地生成数据而不是从一个固定的数据集合中返回数据。Python中的生成器是通过yield关键字来实现的。当函数中包含yield时,该函数就成为生成器函数,并返回一个生成器对象。

1.yield 生成器

示例1:

def num_generator(n):
    for i in range(1, n+1):
        yield i

# 使用生成器函数生成1到10的数字序列
print(type(num_generator(10)))
for num in num_generator(10):
    print(num)

输出

<class 'generator'>
1
2
3
4
5
6
7
8
9
10

其中,生成器函数num_generator()使用yield语句生成数字序列,并在每次调用时返回一个值。使用for循环迭代生成器对象,每次迭代从生成器函数中获取一个值并打印。

2.元组生成器

示例2:

tuple_generator = (i for i in range(10))
result_tuple = tuple(tuple_generator)
print(type(tuple_generator))
print(type(result_tuple))
print(result_tuple)

输出结果

<class 'generator'>
<class 'tuple'>
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)

在这个例子中,我们使用了生成器表达式 (i for i in range(10)) 来生成一个可迭代对象,然后使用 tuple() 函数将其转换为元组。

3.生成器中重要方法

next、send、throw是生成器中的3个重要方法,其中next和send可用于遍历生成器,throw用于抛出异常。

其中next函数使用时,当已经遍历到生成器的结尾,会抛一个异常StopIteration
其中send函数使用时,生成器的第一个值必须使用send(None)
其中throw效果等同于raise

生成器的优点是节省内存,因为它不会一次性生成所有值,而是逐个生成并在使用后释放内存。另外,生成器可以通过迭代器协议与其他Python对象进行交互,包括列表、字典等等。

四、装饰器

1.函数装饰器

Python装饰器是一种高级语法,它可以在不修改原函数代码的情况下,增加或改变原函数的功能。装饰器本质上是一个函数,它可以接收一个函数作为参数,并返回一个新的函数。

@decorator
def function():
    pass

其中 decorator 是一个装饰器函数,用于增强 function 函数的功能。装饰器函数的定义如下:

def decorator(func):
    def wrapper(*args, **kwargs):
        # 在这里增加或改变 func 函数的功能
        print(f'calling {func.__name__}()')
        return func(*args, **kwargs)
    return wrapper

装饰器函数 decorator 接收一个函数 func,并返回一个新的函数 wrapper。wrapper 函数可以在调用原函数之前或之后执行一些操作,然后调用原函数并返回其结果。

计时器示例:

import datetime

def timer(func):
    def wrapper(*args, **kwargs):
        start_time = datetime.datetime.now()
        result = func(*args, **kwargs)
        end_time = datetime.datetime.now()
        print('{0} run time is {1}'.format(func.__name__, (end_time - start_time).total_seconds()))
        return result
    return wrapper

@timer
def my_function():
    time.sleep(2)
    print("Function complete.")

my_function()

其中 timer函数是装饰器函数,它接受一个函数作为参数,返回一个新函数wrapper。wrapper函数用于记录被装饰函数执行的时间,并在执行完毕后输出时间。最后,将my_function函数使用@timer装饰器修饰,从而实现函数计时的功能。
在这里插入图片描述

2.可传参函数装饰器

装饰器函数也是函数,既然是函数,那么就可以进行参数传递,咱们怎么写一个带参数的装饰器呢

import datetime

def time_msg(msg=None):
    def timer(func):
        def wrapper(*args, **kwargs):
            start_time = datetime.datetime.now()
            result = func(*args, **kwargs)
            end_time = datetime.datetime.now()
            print('{0}:{1} run time is {2}'.format(msg,func.__name__, (end_time - start_time).total_seconds()))
            return result
        return wrapper
    return timer

@time_msg(msg="baiyu")
def my_function():
    time.sleep(2)
    print("Function complete.")

my_function()

在这里插入图片描述

3.类装饰器

在python中,可以用类来实现装饰器的功能,称之为类装饰器。类装饰器的实现是调用了类里面的__call__函数。类装饰器的写法比我们装饰器函数的写法更加简单。

import datetime

class MyDecorator:
    def __init__(self, func):
        self.func = func
        print("执行类的__init__方法")
 
    def __call__(self, *args, **kwargs):
        print('进入__call__函数')
        start_time = datetime.datetime.now()
        result = self.func(*args, **kwargs)
        end_time = datetime.datetime.now()
        print('{0}:{1} run time is {2}'.format('',self.func.__name__, (end_time - start_time).total_seconds()))
        result.atrr = '自定义附加参数'  # 类调用时可
        return result 

@MyDecorator
def my_function():
    time.sleep(2)
    print("Function complete.")

@MyDecorator
class MyClass:
    print("MyClass.")

# my_function()

obj = MyClass()
print(obj.attr) # '附加参数'

在这里插入图片描述
在这里插入图片描述

4.可传参的类装饰器

import datetime

class MyDecorator(object):
    def __init__(self, arg1, arg2):
        self.arg1 = arg1
        self.arg2 = arg2
 
    def __call__(self,func):
        print('进入__call__函数')
        def wrapped(*args, **kwargs):
            print("Decorator arguments:", self.arg1, self.arg2)
            start_time = datetime.datetime.now()
            result = func(*args, **kwargs)
            end_time = datetime.datetime.now()
            print('{0}:{1} run time is {2}'.format('',func.__name__, (end_time - start_time).total_seconds()))
            result.attr = '自定义附加参数'  # 类调用时可用
            return result 
        return wrapped

@MyDecorator('参1','参2')
class MyClass:
    print("MyClass.")

obj = MyClass()
print(obj.attr) # '附加参数'

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/666560.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

谈谈电商API!

近年来&#xff0c;随着互联网和移动互联网技术的不断发展&#xff0c;电商行业成为了一种新兴的商业模式。电商平台实现了互联网和商品销售的深度融合&#xff0c;成为经济社会发展的重要组成部分。而电商API&#xff08;Application Programming Interface, 应用程序接口&…

RobotFrameWork Web自动化测试之测试环境搭建

前言 Robot Framework是一款python编写的功能自动化测试框架。具备良好的可扩展性&#xff0c;支持关键字驱动&#xff0c;可以同时测试多种类型的客户端或者接口&#xff0c;可以进行分布式测试执行。主要用于轮次很多的验收测试和验收测试驱动开发&#xff08;ATDD&#xff…

自然语言处理实战项目11-阅读理解项目的数据处理与训练详细讲解,实验结果与分析

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下自然语言处理实战项目11-阅读理解项目的数据处理与训练详细讲解&#xff0c;阅读理解任务目标是让计算机从给定的文章中理解并回答问题。为了完成这个任务&#xff0c;我们需要对给定的数据进行处理和训练。该任务是…

项目调研丨多区块并行处理公链 Transformers 研究报告

目录 一、项目简介 二、项目愿景 三、特色和优势 &#xff08;1&#xff09;速度 &#xff08;2&#xff09;安全 &#xff08;3&#xff09;可扩展性 &#xff08;4&#xff09;高度定制 &#xff08;5&#xff09;不可篡改 &#xff08;6&#xff09;所有数据公开透…

怎么防止数据重放攻击——CBC模式【密码学】(7)

目录 一、什么是CBC模式 二、初始化向量 三、异或运算 四、密钥少一位会有影响吗 一、什么是CBC模式 CBC模式中&#xff0c;明文分组在加密前&#xff0c;要与前一组的密文分组进行异或运算&#xff0c;异或运算的结果参与加密函数的运算。 每一个密文分组&#xff0c;都…

解决谷歌翻译无法使用

谷歌翻译无法使用是谷歌官方关闭了中国地区翻译服务。 废话不多说直接上教程&#xff0c;本质就是通过修改hosts文件让translate.googleapis.com域名的IP解析到国内的谷歌服务器IP&#xff0c;网上大部分的教程也是如此。 但是有个问题就是这个IP不稳定可能用了几天就不用了&am…

leetcode 150. 逆波兰表达式求值

2023.6.20 后缀表达式也是栈的经典应用&#xff0c;注意好细节就行&#xff0c;下面直接上代码&#xff1a; class Solution { public:int evalRPN(vector<string>& tokens) {stack<long long> stk;long long result 0;for(int i0; i<tokens.size(); i){i…

兼容性测试对于软件测试来说重要吗?

该测试是软件测试的一个重要部分&#xff0c;它也获得了越来越多的关注和重视。那么&#xff0c;兼容性测试对于软件测试来说重要吗&#xff1f;我们一起往下了解。 首先&#xff0c;兼容性测试可以确保软件在不同的操作系统、硬件平台和设备上能够正常运行。在产品开发过程中&…

Git进阶系列 | 2. Git中的分支策略

Git是最流行的代码版本控制系统&#xff0c;这一系列文章介绍了一些Git的高阶使用方式&#xff0c;从而帮助我们可以更好的利用Git的能力。本系列一共8篇文章&#xff0c;这是第2篇。原文&#xff1a;Branching Strategies in Git[1] 几乎所有的版本控制系统(VCS)都有某种类型的…

【开发细节】SpringBoot项目将接口从HTTP换为HTTPS

证书准备 首先需要生成一个 SSL 证书&#xff0c;可以使用 OpenSSL 工具或者自己的 CA 颁发机构来生成证书&#xff0c;这里就不赘述了。如果是测试阶段&#xff0c;也可以使用 self-signed certificate。 直接使用jdk的keytool生成&#xff0c;具体操作方法如下&#xff1a; …

一个好看美观的登录注册界面的实现

序言&#xff1a;之前介绍那个博客&#xff0c;然后自己搞了这个界面。最近有人和我要&#xff0c;把代码给大家贴出来&#xff0c;提供参考。 首先是这个界面哈 <!DOCTYPE html> <html lang"en"> <head><script src"../static/lib/jquer…

不走弯路!记一个Appium框架运行的实例

目录 前言&#xff1a; 一、框架环境安装 二、测试流程操作 1、安装APK 2、启动 3、服务参数配置 4、脚本录制操作 5、脚本编写 6、脚本执行 三、测试总结 前言&#xff1a; Appium是一个开源的自动化测试框架&#xff0c;用于移动应用程序的自动化测试。它支持在iOS和Andro…

python:使用Scikit-image库的slic函数分割遥感图像

作者:CSDN @ _养乐多_ 本文记录了使用Scikit-image库的skimage.segmentation模块中的slic函数,进行超像素分割的代码。 文章目录 一、slic函数详解二、代码一、slic函数详解 在Scikit-image库的skimage.segmentation模块中,slic函数用于进行超像素分割。该函数的参数含义如…

62、基于51单片机手机APP蓝牙调试助手控制四个LED灯的开关系统设计(程序+原理图+PCB源文件+Proteus仿真+外文文献翻译+元器件清单等)

方案选择 单片机的选择 方案一&#xff1a;AT89C52是美国ATMEL公司生产的低电压&#xff0c;高性能CMOS型8位单片机&#xff0c;器件采用ATMEL公司的高密度、非易失性存储技术生产&#xff0c;兼容标准MCS-51指令系统&#xff0c;片内置通用8位中央处理器(CPU)和Flash存储单元…

CRM选型之CRM系统要不要自研

如今在外部激烈的竞争环境下&#xff0c;CRM因其具有有效管理客户资源&#xff0c;提升客户体验和满意度的能力&#xff0c;而逐渐成为了企业在运营中必不可收的一部分。然而&#xff0c;在引入CRM系统时&#xff0c;企业面临着选型难题&#xff1a;是自研还是购买第三方的CRM系…

Qt利用paintEvent绘制双Y轴坐标折线图

在项目中&#xff0c;根据需求需要开发双Y轴坐标折线图&#xff0c;但是由于它有多个图层&#xff0c;如果使用QChart绘制的话&#xff0c;达不到需求的要求&#xff0c;只能自己绘制&#xff0c;具体的利用translate()接口将坐标系统移动到界面的左下角(30, height() - 50)处&…

IDEA启动终端报错: Cannot open Local Terminal Failed to start ***

1.问题 打开IDEA后&#xff0c;启动终端发现终端报错没有办法正常使用&#xff0c;错误提示 Cannot open Local Terminal Failed to start [powershell.exe] in D:\vue_admin Error running process: CreateProcess failed. Code 2 See IDE log (Help | Show Log in Explorer…

开源创新,燃起未来的火花

尊敬的各位嘉宾、领导、专家、企业代表、优秀开发者和创新人才们&#xff1a; 在2023年6月11日至13日&#xff0c;开放原子全球开源峰会盛大召开&#xff0c;汇集了众多业界精英和开源领域的专家学者&#xff0c;为探索开源创新的辉煌未来共同助力。作为一名开源技术爱好者&am…

开放式耳机的优缺点有哪些?目前有什么开放式耳机推荐?

什么是开放式耳机&#xff1f; 从名字上理解就是开放样式的耳机&#xff0c;其实也确实如此&#xff0c;开放式耳机是不需要封闭耳道来传输声音&#xff0c;主要是通过耳骨振动传递或者声波震动耳膜&#xff0c;两者声音传递的方式都不用完全封闭耳道&#xff0c;可以让耳道对…

COMSOL导入图片几何模型-以二维多孔介质为例

建模教程 首先获取一张多孔介质图片&#xff0c;这里就以COMSOL官网教程图片为例 通过软件将png格式的图片转换为DXF格式文件&#xff0c;也就是AutoCAD支持的文件&#xff1a; 下一步打开COMSOL软件建立二维模型&#xff0c;导入事先准备好的dxf模型&#xff0c;需要注意导入…