copy函数+不/可变对象,python实现list每个元素依次左移

2024-04-26 01:08

本文主要是介绍copy函数+不/可变对象,python实现list每个元素依次左移,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Python实现list的所有元素左移一个位置,且将所有结果保存成一个list
例如:[1,2,3,4,5]
输出:[[1,2,3,4,5], [2,3,4,5,1], [3,4,5,1,2], [4,5,1,2,3], [5,1,2,3,4]]

天真烂漫

lt = [1, 2, 3, 4, 5]
end=[]
l=len(lt)
for i in range(l):lt.append(lt.pop(0))end.append(lt)print(end)
>>>[[1, 2, 3, 4, 5], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5]]

看到结果的我是有点蒙逼的???为何会这样,end每一步append的元素,最后为何变成一样的了?立刻意识到这个问题不简单,半路出家的我知道我该去看看list的底层实现了。
但在这之前,我先看了python的可变与不可变对象。

python的可变与不可变对象

不可变对象:对象存放在地址中的值不会被改变,当想要修改对象时,会新创建一个地址来存放改变后的值,而原来的对象并不发生改变;而且当两个对象的值一样的时候,只有一个地址存放,两个对象都指向这个地址。

可变对象:对象存放在地址中的值会原地改变

int str float tuple 属于不可变对象 其中tuple更与众不同

dict set list 属于可变对象


那么也就是说,list作为可变对象,end每次append的时候,是原地改变的,

lt = [1, 2, 3, 4, 5]
end=[]
for i in range(len(lt)):print(id(lt))lt.append(lt.pop(0))print(id(lt))end.append(lt)print(end)
>>>
2897136022472
2897136022472
2897136022472
2897136022472
2897136022472
2897136022472
2897136022472
2897136022472
2897136022472
2897136022472
[[1, 2, 3, 4, 5], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5]]

从id的结果可以看出来,确实列表的id一直没有变。再debug过程中观察
在这里插入图片描述
在这里插入图片描述
当再一次为end加入元素时,会在原有的列表基础上进行修改,只不过这次连接的是两个lt,而lt对象指向的内存地址中的值是[3, ,4, 5, 1, 2]所以end就会改变。这时可以用copy函数解决这个问题,这里说明一下copy函数。


python传递变量值的三种形式:赋值,浅拷贝,深拷贝

  • 基本数据类型
    在Python中基本数据类型(整型、字符串、布尔及None)的赋值、深浅拷贝没有任何意义,都是指向同一块内存地址,也不存在层次问题。
import copy
n1 = 'abc'
n2 = n1
n3 = copy.copy(n1)
n4 = copy.deepcopy(n1)
print(id(n1))    #输出140350336680040
print(id(n2))    #输出140350336680040
print(id(n3))    #输出140350336680040
print(id(n4))    #输出140350336680040
  • 列表、元组、字典等非基本数据类型对象的赋值、深浅拷贝的区别

假设字典n1 = {“k1”: “abc”, “k2”: 123, “k3”: [“abc”, 123]}

赋值是将变量的内存赋给另一个变量,让另一个变量指向那个内存地址
在这里插入图片描述

  1. 浅拷贝
    在内存中将第一层额外开辟空间进行存放
    在这里插入图片描述
n1 = {"k1": "abc", "k2": 123, "k3": ["abc", 123]}   
print(id(n1))    #140350328984328
n3 = copy.copy(n1)
print(id(n3))    #140350328986504可以看n3的内存地址已经和n1不同了print(id(n1['k3']))    #140350328603976
print(id(n3['k3']))    #140350328603976 字典里的列表还是指向同一个列表

2.深拷贝

深拷贝就是在内存中将数据重新创建一份,不仅仅是第一层,第二层、第三层…都会重新创建
在这里插入图片描述

n1 = {"k1": "abc", "k2": 123, "k3": ["abc", 123]}
print(id(n1))    #140350328984328
n3 = copy.deepcopy(n1)print(id(n1['k3']))    #140350328603976
print(id(n3['k3']))    #140350328604296 
#可以看到第二层的列表也拷贝了一份,内存地址已经完全不一样

言归正传,以上的问题既可以结局了

lt = [1, 2, 3, 4, 5]
end=[]
for i in range(len(lt)):lt.append(lt.pop(0))end.append(lt.copy())print(end)
>>>[[2, 3, 4, 5, 1], [3, 4, 5, 1, 2], [4, 5, 1, 2, 3], [5, 1, 2, 3, 4], [1, 2, 3, 4, 5]]

perfect!

这篇关于copy函数+不/可变对象,python实现list每个元素依次左移的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/936299

相关文章

Python实现批量提取BLF文件时间戳

《Python实现批量提取BLF文件时间戳》BLF(BinaryLoggingFormat)作为Vector公司推出的CAN总线数据记录格式,被广泛用于存储车辆通信数据,本文将使用Python轻松提取... 目录一、为什么需要批量处理 BLF 文件二、核心代码解析:从文件遍历到数据导出1. 环境准备与依赖库

linux下shell脚本启动jar包实现过程

《linux下shell脚本启动jar包实现过程》确保APP_NAME和LOG_FILE位于目录内,首次启动前需手动创建log文件夹,否则报错,此为个人经验,供参考,欢迎支持脚本之家... 目录linux下shell脚本启动jar包样例1样例2总结linux下shell脚本启动jar包样例1#!/bin

go动态限制并发数量的实现示例

《go动态限制并发数量的实现示例》本文主要介绍了Go并发控制方法,通过带缓冲通道和第三方库实现并发数量限制,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录带有缓冲大小的通道使用第三方库其他控制并发的方法因为go从语言层面支持并发,所以面试百分百会问到

Go语言并发之通知退出机制的实现

《Go语言并发之通知退出机制的实现》本文主要介绍了Go语言并发之通知退出机制的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录1、通知退出机制1.1 进程/main函数退出1.2 通过channel退出1.3 通过cont

Python Web框架Flask、Streamlit、FastAPI示例详解

《PythonWeb框架Flask、Streamlit、FastAPI示例详解》本文对比分析了Flask、Streamlit和FastAPI三大PythonWeb框架:Flask轻量灵活适合传统应用... 目录概述Flask详解Flask简介安装和基础配置核心概念路由和视图模板系统数据库集成实际示例Stre

Python实现PDF按页分割的技术指南

《Python实现PDF按页分割的技术指南》PDF文件处理是日常工作中的常见需求,特别是当我们需要将大型PDF文档拆分为多个部分时,下面我们就来看看如何使用Python创建一个灵活的PDF分割工具吧... 目录需求分析技术方案工具选择安装依赖完整代码实现使用说明基本用法示例命令输出示例技术亮点实际应用场景扩

java如何实现高并发场景下三级缓存的数据一致性

《java如何实现高并发场景下三级缓存的数据一致性》这篇文章主要为大家详细介绍了java如何实现高并发场景下三级缓存的数据一致性,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 下面代码是一个使用Java和Redisson实现的三级缓存服务,主要功能包括:1.缓存结构:本地缓存:使

如何在Java Spring实现异步执行(详细篇)

《如何在JavaSpring实现异步执行(详细篇)》Spring框架通过@Async、Executor等实现异步执行,提升系统性能与响应速度,支持自定义线程池管理并发,本文给大家介绍如何在Sprin... 目录前言1. 使用 @Async 实现异步执行1.1 启用异步执行支持1.2 创建异步方法1.3 调用

Spring Boot配置和使用两个数据源的实现步骤

《SpringBoot配置和使用两个数据源的实现步骤》本文详解SpringBoot配置双数据源方法,包含配置文件设置、Bean创建、事务管理器配置及@Qualifier注解使用,强调主数据源标记、代... 目录Spring Boot配置和使用两个数据源技术背景实现步骤1. 配置数据源信息2. 创建数据源Be

在MySQL中实现冷热数据分离的方法及使用场景底层原理解析

《在MySQL中实现冷热数据分离的方法及使用场景底层原理解析》MySQL冷热数据分离通过分表/分区策略、数据归档和索引优化,将频繁访问的热数据与冷数据分开存储,提升查询效率并降低存储成本,适用于高并发... 目录实现冷热数据分离1. 分表策略2. 使用分区表3. 数据归档与迁移在mysql中实现冷热数据分