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

【python】列表“*”方式与推导式方式初始化区别

刷题过程中踩坑(152. 乘积最大子数组),第一次解题代码中将下面代码中的二维dp数组的初始化中通过dp = [[nums[0]] * 2] * len(nums)实现的:

class Solution:def maxProduct(self, nums: List[int]) -> int:dp = [[nums[0]] * 2 for _ in range(len(nums))]  # dp[i][0]:最大值  dp[i][1]:最小值for i in range(1, len(nums)):if nums[i] == 0:dp[i][0] = 0dp[i][1] = 0elif nums[i] > 0:dp[i][0] = max(dp[i - 1][0] * nums[i], nums[i])dp[i][1] = min(dp[i - 1][1] * nums[i], nums[i])else:dp[i][0] = max(dp[i - 1][1] * nums[i], nums[i])dp[i][1] = min(dp[i - 1][0] * nums[i], nums[i])ans = float('-inf')for i in range(len(dp)):if dp[i][0] > ans:ans = dp[i][0]return ans

结果测试用例总是不通过,解题思路似乎也看不出问题,gpt检查是dp数组初始化的问题。

python中,*的方式对列表数乘扩容,如果列表元素是可变类型,修改一个元素的值会影响其它元素,可从下面cpython的源代码中证明:
https://github.com/python/cpython/blob/3.12/Objects/listobject.c#L553
在这里插入图片描述

如果列表长度为1,源码574行直接开辟n个长度的空间并复制列表首元素的地址;如果列表长度>1,581~582行将原列表的前n个元素地址复制到新列表的前n个元素位置,585~586行直接将新列表中前n和位置元素的地址批量复制到后面的内存空间。

其实本质上来说,python列表的数乘运算,底层都是引用复制,区别在于引用对象是可变对象还是不可变对象,可变对象修改其中一个会影响其它所有副本,不可变对象修改会重新开辟内存空间,不影响副本。

验证demo:

a = [[1, 2]] * 3
print(a)
print([id(item) for item in a])a[0][0] = 3
print(a)
print([id(item) for item in a])# [[1, 2], [1, 2], [1, 2]]
# [4309240192, 4309240192, 4309240192]
# [[3, 2], [3, 2], [3, 2]]
# [4309240192, 4309240192, 4309240192]
a = [1] * 3
print(a)
print([id(item) for item in a])a[0] = 3
print(a)
print([id(item) for item in a])# [1, 1, 1]
# [4326971552, 4326971552, 4326971552]
# [3, 1, 1]
# [4326971616, 4326971552, 4326971552]

可通过列表推导式的方式初始化,这样对于可变类型对象每次都会重新开辟内存空间,修改不相互影响:

a = [[1, 2] for _ in range(3)]
print(a)
print([id(item) for item in a])# [[1, 2], [1, 2], [1, 2]]
# [4343746688, 4345649152, 4345315968]
http://www.dtcms.com/a/306984.html

相关文章:

  • 数据结构——单链表1
  • 【WRF-Chem】EDGAR 排放数据处理:分部门合并转化为二进制(Python全代码)
  • RAG实战指南 Day 27:端到端评估框架实现
  • CSS-in-JS 动态主题切换与首屏渲染优化
  • 1.5.Vue v-for 和 指令修饰符
  • COZE 开源,新一代 AI Agent 本地部署一条龙
  • Excel文件解析
  • OpenWrt Network configuration
  • 百度统计在哪里添加网站?
  • Linux系统启动不受未挂载硬盘影响的解决方案
  • Windows系统使用命令生成文件夹下项目目录树(文件结构树)的两种高效方法
  • 深度学习-丢弃法 Dropout
  • C语言基础11——结构体1
  • Qt Quick 动画与过渡效果
  • QT中QTableView+Model+Delegate实现一个demo
  • TikTok 视频审核模型:用逻辑回归找出特殊类型的视频
  • 全栈:SSH和SSM和Springboot mybatisplus有什么区别?
  • 以ros的docker镜像为例,探讨docker镜像的使用
  • 力扣刷题日常(7-8)
  • 【Arch-Linux,hyprland】常用配置-已实验成功指令大全(自用)(持续更新)
  • 如何保证数据库的持久性与一致性:从 Linux 磁盘缓存策略到 MySQL 的设计
  • 执业药师证识别技术:医药健康生态中发挥愈发关键的作用
  • 微软:科技领域的创新巨头
  • Sleeping Cup 论坛:连接开发者与创新的桥梁
  • 隧道COVI检测器的用处
  • [SKE]使用OpenSSL库实现AES、SM4、DES、RSA、3DES_EDE和3DES_EEE算法的加解密验证
  • SringBoot入门
  • Linux启动防火墙提示提示 Active: failed (Result: timeout)
  • Golang 指针与引用深度解析:对比 C/C++ 的内存管理哲学
  • Jupyter Notebook安装使用