首頁 > 軟體

python中list.copy方法用法詳解

2023-02-09 06:01:32

當我們想複製兩個一模一樣的列表時,我們可能使用到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])**變得不一樣了

總結

到此這篇關於python中list.copy方法用法的文章就介紹到這了,更多相關python list.copy方法內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com