網站首頁 編程語言 正文
當我們想復制兩個一模一樣的列表時,我們可能使用到list.copy()這個方法,這個方法可以讓我們復制一個相同的數組,當遇到下面這種情況時,可能會遇到一些問題
# _*_coding='utf8'_*_
nameList = [1, 2, 3, 4, 5]
nameList1 = nameList.copy()
nameList[1] = 55
print(nameList, nameList1)
此時打印出nameList和nameList1時,兩個列表的元素是下面這樣
[1, 55, 3, 4, 5] [1, 2, 3, 4, 5]
可以看到列表的第二個元素不一樣
這是因為在python中list.copy()這個函數在執行的時候,指向的不是nameList在內存中的地址,而是重新復制了一份,此時兩個列表在內存中的地址不同,我們可以打印出來看看
使用如下代碼可以見到,兩個列表的內存已經有差別了
nameList = [1, 2, 3, [3, 4, 5], 4, 5]
nameList1 = nameList.copy()
nameList[1] = 55
print(id(nameList), id(nameList1))
2207528867520 2207531826048
此時修改的nameList[1] = 55并不會在nameList1中生效
而當nameList中又存在數組時,情況又會發生變化
# _*_coding='utf8'_*_
nameList = [1, 2, 3, [3, 4, 5], 4, 5]
nameList1 = nameList.copy()
nameList[3][2] = 55
print(nameList, nameList1)
輸入如下內容
[1, 2, 3, [3, 4, 55], 4, 5] [1, 2, 3, [3, 4, 55], 4, 5]
可以看到兩個list中嵌套的數組都發生了變化,這是因為在列表中存放的二維列表,實際上存放的是二維列表在內存中的地址,當修改其中一個列表,另外一個自然也會受到影響,那么,讓我們來驗證一下是不是存放的內存地址。
同樣的,我們使用id()這個方法來取出內存地址
# _*_coding='utf8'_*_
nameList = [1, 2, 3, [3, 4, 5], 4, 5]
nameList1 = nameList.copy()
nameList[3][2] = 55
print(id(nameList[3]), id(nameList1[3]))
輸出如下內容
2879859422336 2879859422336
可以看到,兩個內存地址是相同的
copy方法介紹到此結束
補充:python list.copy() 和 copy.deepcopy()區別
舉個例子
import copy
class ListNode:
def __init__(self, x):
self.val = x
self.next = None
def __repr__(self):
return str(self.val)
list1 = [ListNode(1), ListNode(2)]
list2 = list1.copy()
list3 = list1[:]
list4 = copy.deepcopy(list1)
print(list1, list2, list3, list4)
# [1, 2] [1, 2] [1, 2] [1, 2]
list1[0].val = 5
print(list1, list2, list3, list4)
# [5, 2] [5, 2] [5, 2] [1, 2]
list1.append(ListNode(10))
print(list1, list2, list3, list4)
# [5, 2, 10] [5, 2] [5, 2] [1, 2]
print(id(list1[0]),id(list2[0]),id(list3[0]),id(list4[0]))
# 1984073709792 1984073709792 1984073709792 1984073707824
解釋
- list1 是原數組
- list2 和 list3 都是list1的淺拷貝,淺拷貝到底是什么意思?
python的list里面存的都是引用,如果存的是listnode,實際上存的是listnode的引用,也就是地址,畢竟如果listnode里存了很多關于這個node的信息的話,直接在list里面存這段信息的地址就很方便,等到要用這段信息的時候(比如list1[0].val),只要找到地址(list1[0])再到這段地址取值(.val)就可以了。
淺拷貝的意思是,開辟一段內存,這段內存里復制了原list的地址。
地址還是那個地址,所以可以看出**id(list1[0]),id(list2[0])**是完全一樣的。這會帶來的問題是,當我們把這段地址里的值.val變化一下(list1[0].val = 5), 淺拷貝的數組里對應元素的值也就跟著變了
深拷貝就厲害了,不光把原數組存的地址拷貝了,就連原數組地址里對應的數據也都進行了復制,所以可以看到**id(list1[0]),id(list4[0])**變得不一樣了
總結
原文鏈接:https://blog.csdn.net/u014572617/article/details/119846387
相關推薦
- 2022-09-02 pytest使用@pytest.mark.parametrize()實現參數化的示例代碼_pytho
- 2022-08-16 C#?IEnumerator枚舉器的具體使用_C#教程
- 2022-05-27 C++?二叉樹的實現超詳細解析_C 語言
- 2022-04-26 SQL將一個表中的數據插入到另一個表中的方法_MsSql
- 2022-01-15 解決npm install 報錯 npm ERR! code 128 npm ERR! comman
- 2022-07-11 Docker 安裝redis
- 2022-01-27 editor.md第一行解析失敗,解析成代碼模塊原始輸出
- 2022-05-20 詳解在SQLPlus中實現上下鍵翻查歷史命令的功能_MsSql
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支