当前位置: 首页 > news >正文

Python小记:星号解包的妙用

最近在学习 Python asyncio,过程中遇到一段代码:

await asyncio.gather(*(generate_random(num) for num in values))

初看这段代码就有一种熟悉的感觉,但是太久没有写 Python,并没有立刻反应过来 * 在这里到底在做什么。再三思考之后才回忆起来:这里的 * 是迭代器解包(iterable unpacking),把生成器表达式产出的多个值解包成多个独立参数,再传递给外层调用函数。写下这篇文章做个记录,方便以后温故知新。


为了真正理解 *,先来看一个基础的场景。假设有一个函数需要接收多个位置参数:

def demo(a, b, c):print(a, b, c)

如果已经有一个可迭代对象,比如一个列表:

values = [1, 2, 3]

那么下面两种写法是等价的:

demo(*values)   # 1 2 3
demo(1, 2, 3)   # 1 2 3

这里 * 的作用就是:把可迭代对象"拆开",变成多个独立的位置参数再传进去。

import asyncio
import randomasync def main():values = [1, 2, 3]await asyncio.gather(*(generate_random(num) for num in values))async def generate_random(num):print(f"{num} random number is {random.uniform(0.1, 1.0)}")await asyncio.sleep(2)if __name__ == "__main__":import timestart = time.perf_counter()random.seed(49)asyncio.run(main())end = time.perf_counter()print(f"\n==> Total time: {end - start:.2f} seconds")

如果不是生成器而是列表,那么星号能否起作用呢?答案是可以的。上面的代码也可以写成列表推导式:

await asyncio.gather(*[generate_random(num) for num in values])

两种写法在运行结果上没有区别,不过有一个点要留意:生成器表达式是惰性的。

  • 列表推导式会一次性把所有对象生成出来,先构建一个完整列表;
  • 生成器表达式则是每次迭代时才真正创建对象。

asyncio.gather 中,无论使用生成器表达式还是列表推导式,所有协程都会并发执行,生成器的惰性特质主要体现在内存使用上。当 values 数量比较多或者 generate_random 函数运行比较耗时(比如涉及 I/O)的情况下,生成器不会一次性占用大量内存,这个特质作用就会很大。


最后小结

总体来看 * 不只是"不定参数",还可以用来做可迭代对象/列表的解包。在使用 asyncio.gather 时,* 可以将生成器表达式或列表推导式产生的多个协程对象解包为独立参数传递给 gather 函数,实现并发执行。

附参考

  • Python's asyncio: A Hands-On Walkthrough https://realpython.com/async-io-python/
http://www.gsyq.cn/news/1484602.html

相关文章:

  • 如何快速构建专业数据监控界面:Node-RED Dashboard实战指南
  • AI Orchestration:MuleSoft与LangChain的企业级协同架构
  • 从抓包到内核参数:图解NAT环境下TCP连接被RST的完整诊断流程(以F5+LVS为例)
  • 3步掌握哔哩下载姬:B站视频批量下载与高级格式支持完全指南
  • 遗传算法工程化实战:适应度设计、算子适配与收敛诊断
  • 数据科学求职通关:知识如何转化为可验证的交付能力
  • Dense X Retrieval:RAG中稠密检索与交叉编码器重排序的工程实践
  • 5G/6G仿真选哪个?TDL与CDL信道模型实战对比与避坑指南
  • 告别闪退!用Maven Assembly Plugin和exe4j打包JavaFX应用(附JRE配置避坑指南)
  • N皇后遗传算法Python实操:从卡死到跑通100解
  • 不到30元自制无线脚踏宏:用KMS-4-WF模块把旧开关改成游戏/办公神器
  • 告别瞎点!UG NX 12 点构造器全解析:从“光标位置”到“按表达式”,一次搞懂所有定位逻辑
  • 2026年众智商学院SCMP报名费用和班期怎么确认?官网入口及试听课资料领取咨询 - 众智商学院官方
  • 手把手教你为海思Hi3516DV300交叉编译hostapd 2.9,搭建嵌入式WiFi热点(附完整依赖库编译)
  • MixIO vs Blynk/MQTT:一个更适合Mixly用户的物联网平台选择指南
  • 别再让静电搞坏你的电机!手把手教你用EFT/ESD测试仪排查工业驱动器EMC问题
  • 深入浅出:Android开发中的Gradle依赖管理与冲突解决
  • SAP MM配置实战:手把手教你用OMS4定义物料状态,精准控制物料生命周期
  • 微信小程序NFC碰一碰拓客源码(含安装文档与核心JS逻辑)
  • 用FRDM-KL25Z开发板做个《新版西蒙》游戏:从触摸到PWM调光的完整实战
  • Microsemi Libero Soc v11.9 安装与证书获取保姆级避坑指南(Win10实测)
  • 手把手教你用Calibration Curve和概率直方图,诊断并修复SVM、朴素贝叶斯的‘自信不足’或‘过度自信’问题
  • 遗传算法工程实践:从轮盘赌选择到自适应变异的可调试实现
  • 无人机多模态盘点系统:空间感知型库存管理新范式
  • 别再傻傻分不清了!一文搞懂电磁继电器和磁保持继电器的区别与选型
  • 别再死记硬背了!用Java手搓一个图结构,把DFS、BFS、Dijkstra都跑一遍
  • MOEA/D多目标优化MATLAB工具包:含测试函数、权重生成与双变异策略
  • ESP32蓝牙主从通信避坑指南:为什么你的回调函数不触发?
  • 别再只用RAID了!聊聊分布式存储里EC纠删码的实战选型(4+2还是6+3?)
  • 告别jom构建噩梦:一份给QtCreator+CMake新手的MSVC环境配置自查清单