python2.7中複製資料模型(可變與不可變模型)的幾個坑
python2.7中對於不同的資料模型對於不同的複製方式會出現不一樣的結果,平時工作中遇到很多坑,總結如下。
一、不可變資料模型(整型int、浮點型float、字串型string和元組tuple)
-
第1種:通過等號[=]複製
originalStr = 'nanjing'
anotherStr = originalStr # [=]號複製
print '複製前後是否為同一記憶體地址: %s' % (id(originalStr) == id(anotherStr))
nowCity = 'nantong'
print '原字串: nanjing, 現字串: %s' % originalStr
---
複製前後是否為同一記憶體地址: True
原字串: nanjing, 現字串: nanjing
-
第2種:通過工廠方法複製
originalStr = 'nanjing'
anotherStr = str(originalStr) # 通過str()
print '複製前後是否為同一記憶體地址: %s' % (id(originalStr) == id(anotherStr))
nowCity = 'nantong'
print '原字串: nanjing, 現字串: %s' % originalStr
---
複製前後是否為同一記憶體地址: True
原字串: nanjing, 現字串: nanjing
第3種:通過淺拷貝(copy)方法複製
import copy
originalStr = 'nanjing'
anotherStr = copy.copy(originalStr) # 淺拷貝,只拷貝頂級物件
print '複製前後是否為同一記憶體地址: %s' % (id(originalStr) == id(anotherStr))
nowCity = 'nantong'
print '原字串: nanjing, 現字串: %s' % originalStr
---
複製前後是否為同一記憶體地址: True
原字串: nanjing, 現字串: nanjing
第4種:通過深拷貝(deepcopy)方法複製
import copy
originalStr = 'nanjing'
anotherStr = copy.deepcopy(originalStr) # 深拷貝,拷貝頂級物件及巢狀物件
print '複製前後是否為同一記憶體地址: %s' % (id(originalStr) == id(anotherStr))
nowCity = 'nantong'
print '原字串: nanjing, 現字串: %s' % originalStr
---
複製前後是否為同一記憶體地址: True
原字串: nanjing, 現字串: nanjing
二、可變資料模型列表list、字典dict
-
第1種:通過等號[=]複製
originalList = ['nanjing', [1, 2]]
anotherList = originalList # [=]號複製
print '複製前後是否為同一記憶體地址: %s' % (id(originalList) == id(anotherList))
anotherList[0] = 'nantong'
anotherList[1].append(3)
print "原列表: ['nanjing', [1, 2]], 現列表: %s" % originalList
--
複製前後是否為同一記憶體地址: True
原列表: ['nanjing', [1, 2]], 現列表: ['nantong', [1, 2, 3]]
-
第2種:通過工廠方法複製
originalList = ['nanjing', [1, 2]]
anotherList = list(originalList) # 通過list()複製
print '複製前後是否為同一記憶體地址: %s' % (id(originalList) == id(anotherList))
anotherList[0] = 'nantong'
anotherList[1].append(3)
print "原列表: ['nanjing', [1, 2]], 現列表: %s" % originalList
---
複製前後是否為同一記憶體地址: False
原列表: ['nanjing', [1, 2]], 現列表: ['nanjing', [1, 2, 3]]
-
第3種:通過[:](值傳遞)複製
originalList = ['nanjing', [1, 2]]
anotherList = originalList[:] # 通過[:]複製
print '複製前後是否為同一記憶體地址: %s' % (id(originalList) == id(anotherList))
anotherList[0] = 'nantong'
anotherList[1].append(3)
print "原列表: ['nanjing', [1, 2]], 現列表: %s" % originalList
---
複製前後是否為同一記憶體地址: False
原列表: ['nanjing', [1, 2]], 現列表: ['nanjing', [1, 2, 3]]
-
第4種:通過淺拷貝(copy)方法複製
import copy
originalList = ['nanjing', [1, 2]]
anotherList = copy.copy(originalList) # 淺拷貝,只拷貝頂級物件
print '複製前後是否為同一記憶體地址: %s' % (id(originalList) == id(anotherList))
anotherList[0] = 'nantong'
anotherList[1].append(3)
print "原列表: ['nanjing', [1, 2]], 現列表: %s" % originalList
---
複製前後是否為同一記憶體地址: False
原列表: ['nanjing', [1, 2]], 現列表: ['nanjing', [1, 2, 3]]
-
第5種:通過深拷貝(deepcopy)方法複製
import copy
originalList = ['nanjing', [1, 2]]
anotherList = copy.deepcopy(originalList) # 深拷貝,拷貝頂級物件及巢狀物件
print '複製前後是否為同一記憶體地址: %s' % (id(originalList) == id(anotherList))
anotherList[0] = 'nantong'
anotherList[1].append(3)
print "原列表: ['nanjing', [1, 2]], 現列表: %s" % originalList
---
複製前後是否為同一記憶體地址: False
原列表: ['nanjing', [1, 2]], 現列表: ['nanjing', [1, 2]]
初步總結
第1種:通過等號[=]複製
- 不論可變還是不可變資料型別,通過[=]複製後都指向同一個記憶體地址;
- 改變複製後的資料(例子中的anotherStr,anotherList),原資料中不可變資料模型值未改變,可變資料模型值改變
-
第2種:通過工廠方法複製
- 不可變資料模型複製後指向同一個記憶體地址,可變資料模型指向不同地址;
- 改變複製後的資料(例子中的anotherStr,anotherList),原資料中不可變資料模型值未改變,可變資料模型值改變
-
第3種:通過[:](值傳遞)複製
- 不可變資料模型不涉及;可變資料模型指向不同記憶體地址;
- 改變複製後的資料(anotherList),原資料中不可變資料模型值未改變,可變資料模型值改變
-
第4種:通過淺拷貝(copy)方法複製
- 不可變資料模型複製後指向同一個記憶體地址,可變資料模型指向不同地址;
- 改變複製後的資料(例子中的anotherStr,anotherList),原資料中不可變資料模型值未改變,可變資料模型值改變
-
第5種:通過深拷貝(deepcopy)方法複製
- 不可變資料模型複製後指向同一個記憶體地址,可變資料模型指向不同地址;
- 改變複製後的資料(例子中的anotherStr,anotherList),原資料中不可變、可變資料模型值均未改變
最終總結
- 對於不可變資料模型,不論通過什麼辦法複製,通過改變複製後的資料,均不會改變原資料的值
- 對於可變資料模型,除深拷貝不會改變原資料值,其他均會改變原資料值
相關文章
- python的不可變物件與可變物件及其妙用與坑Python物件
- Python基礎(一)可變與不可變資料型別Python資料型別
- 可變資料型別(mutable)與不可變資料型別(immutable)總結資料型別
- 8. 深淺複製、可變與不可變、垃圾回收機制、字元編碼、檔案操作字元
- Java中的不可變資料結構Java資料結構
- 資料分析-皮膚資料變截距模型模型
- var+不可變資料結構 vs val+可變資料結構資料結構
- Python - 可變和不可變物件Python物件
- immudb:號稱世界上最快的基於零信任模型的不可變資料庫模型資料庫
- Python可變物件和不可變物件Python物件
- 不可變資料之Immutable
- python中的引用傳遞,可變物件,不可變物件,list注意點Python物件
- Java中的不可變資料結構 - Jworks.ioJava資料結構
- iOS 實現多個可變 cell 複雜介面的製作iOS
- 併發應用中不可變資料結構資料結構
- Python中可變物件和不可變物件的區別?Python基礎Python物件
- 分析模式:可複用的物件模型模式物件模型
- 記錄一次模型 依賴注入 踩過的坑: 控制器方法依賴注入模型變數名與路由變數名必須相同模型依賴注入變數路由
- 大模型時代,中關村科金的蛻變大模型中關村
- 複合材料製造中人工智慧混合資料模型的使用人工智慧模型
- Python中的不可變集合Python
- Java中建立不可變的類Java
- 魚眼相機成像模型和畸變模型模型
- 資料模型與資料分析模型
- 修改全域性變數時,可變型別和不可變型別的區別變數型別
- 大模型時代的AI之變與開發之根大模型AI
- Python語法--可變型別和不可變型別Python型別
- OpenGL模型檢視變換、投影變換、視口變換模型
- Java中的不可變集合,我們換個方式理解!!!Java
- 資料不可變之linked-in/rocketdata
- 機器學習中的模型和資料機器學習模型
- tcp/ip模型中,幀是第幾層的資料單元?TCP模型
- 複製資料庫中需要注意的幾點事項資料庫
- 許可權+訂單資料模型模型
- 36個頂級資料分析方法與模型!模型
- 線上製作資料庫ER模型資料庫模型
- MySQL資料型別及sql模型及伺服器變數MySql資料型別模型伺服器變數
- 資料共享(淺複製)與資料獨立(深複製)