欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python關(guān)于實參隨形參改變而改變的問題

 更新時間:2024年11月20日 08:47:33   作者:長命百歲?  
本文通過實驗總結(jié)了Python中可變和不可變數(shù)據(jù)類型的區(qū)別,并提出了通過使用.copy()方法或deepcopy()函數(shù)來保持可變數(shù)據(jù)不變的解決方案

前言

今天在實驗過程中,發(fā)現(xiàn)將字典作為函數(shù)的形參傳入函數(shù),在函數(shù)內(nèi)改變形參,會導(dǎo)致傳入的字典的值也發(fā)生相應(yīng)的改變。

這與c++不同,令我疑惑,遂寫此文。

簡單實驗

我們對常見的數(shù)據(jù)類型進(jìn)行實驗,檢測形參的該表是否會改變傳入的實參。

變量

def change(a):
    a = 2
    print(a)
b = 1
change(b)
print(b)
>>2
>>1

可見,變量的值并沒有隨形參的改變而改變

元組

def change(a):
    a = a[:2]
    print(a)
b = (1, 2, 3)
change(b)
print(b)
>>(1, 2)
>>(1, 2, 3)

可見,元組沒有隨形參的改變而改變

列表

def change(a):
    a.append(1)
    print(a)
b = [2, 3]
change(b)
print(b)
>>[2, 3, 1]
>>[2, 3, 1]

可見,列表隨著形參的改變而發(fā)生改變

字典

def change(a):
    a[1] = 100
    print(a)
b = {1: 1, 2: 2}
change(b)
print(b)
>>{1: 100, 2: 2}
>>{1: 100, 2: 2}

可見,字典隨著形參的改變而發(fā)生改變

原因

我們遇到了可變不可變數(shù)據(jù)類型之間的差異。在Python中,數(shù)據(jù)類型可以是可變的,也可以是不可變的。

我們通常使用的(整數(shù),浮點數(shù),字符串,布爾值和元組)數(shù)據(jù)類型都是不可變的,但是列表和字典是可變的。

這意味著全局列表或字典即使在函數(shù)內(nèi)部使用時也可以更改,我們通過上面的例子也能看出這個問題。

不可變數(shù)據(jù)舉例

a = 1

變量a 的作用類似于一個指向 1 的指針。

變量的數(shù)據(jù)類型是不可變的,變量一旦創(chuàng)建就不能別改變。

如果我們執(zhí)行 a = a + 1。

我們實際上不是將 1 更新到 2,而是指針從 1 指向了 2。

可變數(shù)據(jù)距離

list1 = [1, 2, 3]

如果我們在列表的末尾添加一個值,我們不是將list1指向另一個列表,而是直接更新現(xiàn)有列表。

如果我們創(chuàng)建多個列表變量,只要他們指向同一個列表,那么當(dāng)列表發(fā)生改變時,這些列表變量都會發(fā)生變化。

list1 = [1, 2, 3]
list2 = list1
list1.append(4)
print(list1)
print(list2)
>>[1, 2, 3, 4]
>>[1, 2, 3, 4]

心得

從這兩個例子中,我們可以直觀感受到可變數(shù)據(jù)類型與不可變數(shù)據(jù)類型之間的區(qū)別。

我們對可變數(shù)據(jù)的操作,是直接在其本身上進(jìn)行操作的。

對不可變數(shù)據(jù)的操作,是將指針指向另一個位置,而不是更改其本身。

保持可變數(shù)據(jù)不變

我們在寫代碼時,經(jīng)常會編寫各種函數(shù)。我們不希望傳入函數(shù)的實參,會在函數(shù)內(nèi)部被改變。那應(yīng)該怎么辦呢?

其實很簡單,使用.copy()方法復(fù)制列表或字典即可。

list1 = [1, 2, 3]
list2 = list1.copy()
list1.append(4)
print(list1)
print(list2)
>>[1, 2, 3, 4]
>>[1, 2, 3]

.copy()方法會創(chuàng)建一個新的副本,這樣list2就不會指向list1指向的列表,而是指向一個新的列表。

這樣的話,list1list2就相互獨立,互不影響了。

def change(a):
    temp = a.copy()
    temp.append(4)
    print(temp)
list1 = [1, 2, 3]
change(list1)
print(list1)
>>[1, 2, 3, 4]
>>[1, 2, 3]

可見,這樣我們就解決了形參的改變帶來的實參改變的問題。對于字典也是一樣的。

補充

深拷貝與淺拷貝

>>> import copy
>>> origin = [1, 2, [3, 4]]
#origin 里邊有三個元素:1, 2,[3, 4]
>>> cop1 = copy.copy(origin)
>>> cop2 = copy.deepcopy(origin)
>>> cop1 == cop2  # 判斷 cop1 和 cop2 的值是否相同
True
>>> cop1 is cop2  # 判斷 cop1 和 cop2 是否是同一個對象
False 
#cop1 和 cop2 看上去相同,但已不再是同一個object
>>> origin[2][0] = "hey!" 
>>> origin
[1, 2, ['hey!', 4]]
>>> cop1
[1, 2, ['hey!', 4]]
>>> cop2
[1, 2, [3, 4]]

copy對于一個復(fù)雜對象的子對象并不會完全復(fù)制。什么是復(fù)雜對象的子對象呢?

比如列表里的嵌套列表(多維列表),字典里的嵌套字典(多維字典)都是復(fù)雜對象的子對象。

對于子對象,python會將其當(dāng)做一個公共鏡像存儲起來,所有對它的復(fù)制都會被當(dāng)成引用(就是拿指針指向同一塊區(qū)域)。所以,其中一個引用的值發(fā)生改變時,其他引用的值也會發(fā)生改變。

復(fù)制復(fù)雜對象,我們也想全盤復(fù)制(包括子對象),這時我們就可以使用deepcopy()函數(shù)進(jìn)行深拷貝

import copy
a = [1, 2, [3, 4]]
b = copy.deepcopy(a)  # 深拷貝

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Python自制圖像批量壓縮工具

    Python自制圖像批量壓縮工具

    這篇文章主要為大家詳細(xì)介紹了如何使用Python自制一個圖像批量壓縮工具,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-04-04
  • PyQt5實現(xiàn)將Matplotlib圖像嵌入到Scoll Area中顯示滾動條效果

    PyQt5實現(xiàn)將Matplotlib圖像嵌入到Scoll Area中顯示滾動條效果

    我想知道是否有一種方法可以在matplotlib上顯示滾動條(水平或垂直),顯示包含多個子槽(sublot2grid)的頁面(plt.show).下面就通過本文給大家分享PyQt5實現(xiàn)將Matplotlib圖像嵌入到Scoll Area中顯示滾動條效果,對PyQt5 Matplotlib圖像嵌入相關(guān)知識感興趣的的朋友一起看看吧
    2021-05-05
  • python爬蟲神器Pyppeteer入門及使用

    python爬蟲神器Pyppeteer入門及使用

    這篇文章主要介紹了python爬蟲神器Pyppeteer入門及使用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-07-07
  • python根據(jù)經(jīng)緯度計算距離示例

    python根據(jù)經(jīng)緯度計算距離示例

    這篇文章主要介紹了python根據(jù)經(jīng)緯度計算距離示例, 計算兩點之間距離,需要的朋友可以參考下
    2014-02-02
  • 淺談python內(nèi)置函數(shù)callable的用法

    淺談python內(nèi)置函數(shù)callable的用法

    這篇文章主要介紹了淺談python內(nèi)置函數(shù)callable的用法, callable函數(shù)可用于判斷一個對象是否可以被調(diào)用,若對象可以被調(diào)用則返回True,反之則返回False,需要的朋友可以參考下
    2023-04-04
  • Python的Django應(yīng)用程序解決AJAX跨域訪問問題的方法

    Python的Django應(yīng)用程序解決AJAX跨域訪問問題的方法

    針對Django中在編寫供AJAX調(diào)用的API時碰到的跨域問題,我們來總結(jié)下Python的Django應(yīng)用程序解決AJAX跨域訪問問題的方法,其中使用GitHub上開源分享的django-cors-headers尤其推薦
    2016-05-05
  • python繪制規(guī)則網(wǎng)絡(luò)圖形實例

    python繪制規(guī)則網(wǎng)絡(luò)圖形實例

    今天小編大家分享一篇python繪制規(guī)則網(wǎng)絡(luò)圖形實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-12-12
  • python 工具類之Queue組件詳解用法

    python 工具類之Queue組件詳解用法

    隊列(queue)是一種先進(jìn)先出的(First In First Out)的線性表,簡稱FIFO。隊列允許在一端進(jìn)行插入操作,而在另一端進(jìn)行刪除操作。允許插入的一端為隊尾,允許刪除的一端為隊頭。隊列不允許在中間部位進(jìn)行操作
    2021-10-10
  • 解決pytorch load huge dataset(大數(shù)據(jù)加載)

    解決pytorch load huge dataset(大數(shù)據(jù)加載)

    這篇文章主要介紹了解決pytorch load huge dataset(大數(shù)據(jù)加載)的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-05-05
  • Python調(diào)用win10toast框架實現(xiàn)定時調(diào)起系統(tǒng)通知

    Python調(diào)用win10toast框架實現(xiàn)定時調(diào)起系統(tǒng)通知

    win10toast是一個windows通知的出發(fā)框架,使用它可以輕松的調(diào)起系統(tǒng)通知。通過它可以很方便的做一個定時通知的功能應(yīng)用。本文將調(diào)用win10toast實現(xiàn)定時調(diào)起系統(tǒng)通知功能,需要的可以參考一下
    2022-01-01

最新評論