python中列表赋值后,改变拷贝列表数值,源列表也会发生变化——浅拷贝

一、浅拷贝和深拷贝

以下文章讲述得很清楚:

面试题:深拷贝和浅拷贝(超级详细,有内存图)_田江的博客-CSDN博客_深拷贝和浅拷贝

python深拷贝和浅拷贝的区别 - 米 立 - 博客园 (cnblogs.com)

python修改列表的值时的地址变化,一个蛮有意思的小实验 - 雾恋过往 - 博客园 (cnblogs.com)

在python中,新建对象赋值实际上是对象的引用。当创建一个对象,然后把它赋给另一个变量的时候,python并没有拷贝这个对象,而只是拷贝了这个对象的引用。

二、Python中浅拷贝

1、了解浅拷贝

列表赋值,也就是浅拷贝,属于引用类型,被赋值的列表与源列表共同引用一个地址,新列表的值发生改变,源列表的值也跟着变化。

import numpy as np

A = [0,1,2,3,4,5,6,7,8]

A1 = A;   
print(A)
print(A1)             #
A1.append(9)
print(A)
print(A1)
print('源列表A中各元素的地址:')
for i in range(len(A)):
    print(id(A[i]))
print('拷贝列表A1中各元素的地址')
for i in range(len(A1)):
    print(id(A1[i]))

 从运行结果中也可以看出A和A1引用了相同的地址。

 2、拷贝分为:

(1)浅拷贝 

A = A1    #改变A1的值,A的值也会发生变化

(2)copy浅拷贝

A1 = A.copy()

#或者

import copy
A1 = copy.copy(A)    #改变A1的值,A的值不会发生改变,除非A中包含子对象,比如:
                     #A = [0,1,2,[3,4,5],6,7,8]
                     #A  copy拷贝给A1之后,若给A1添加一个元素9,则:
                     #A = [0,1,2,[3,4,5],6,7,8]  而A1 = [0,1,2,[3,4,5],6,7,8,9]
                     #若给A1[3]这个元素[3,4,5]添加一个元素9,则:
                     #A = [0,1,2,[3,4,5,9],6,7,8]   A1 = [0,1,2,[3,4,5,9],6,7,8]

(3)深拷贝

import copy
A1 = copy.deepcopy(A)   #深拷贝则是无论A有无子对象,A1改变,A也不会发生改变。

3、代码解释: 

import copy

A = [0,1,2,[3,4,5],6,7,8]
A1 = A                    #1、浅拷贝
#A1 = copy.copy(A)         #2、copy浅拷贝
#A1 = copy.deepcopy(A)     #3、深拷贝
print('源列表:  %s' %A)
print('拷贝列表: %s' %A1)
A1.append(9)
print('A1添加元素后的A列表:%s'%A)
print('A1添加元素后的A1列表:%s'%A1)
A1[3].append(9)
print('A1的子对象添加元素后的A列表:%s'%A)
print('A1的子元素添加元素后的A1列表:%s'%A1)

(1) 浅拷贝

结果可以看出:浅拷贝后,A和A1同步变化。

 (2)copy浅拷贝

 结果可以看到:copy浅拷贝之后,只有A和A1的子对象[3,4,5,9]同步变化。

(3)深拷贝

 结果可以看到:A和A1不同步变化。

 深拷贝为例,了解拷贝原理:

 A1对A深拷贝之后,A1中的子对象[3,4,5]被拷贝到了另外的地址,其他元素依然引用源列表的地址,但在此基础上可以修改,却不改变源列表。

4、应用

python读取dicom图象,然后以不同窗宽显示:

import matplotlib.pyplot as plt
import numpy as np
import pydicom
import cv2
import SimpleITK as sitk
from skimage.morphology import disk, rectangle, binary_dilation, binary_erosion, binary_closing, binary_opening, rectangle, remove_small_objects
import scipy

def read_dicom_data(file_name):
'dicom图象读入'
    file = sitk.ReadImage(file_name)
    data = sitk.GetArrayFromImage(file)
    print(data.shape)
    data = np.squeeze(data, axis=0)
    print(data.shape)
    data = np.int32(data)

    dicom_dataset = pydicom.dcmread(file_name)
    slice_location = dicom_dataset.SliceLocation         #获取层间距
    return data, data.shape[0], data.shape[1], slice_location

def window(window, img_data):
'dicom图象窗宽变换'
    if window == 'Lung':
        img_data[img_data < -1150] = -1150
        img_data[img_data > 350] = 350
    elif window == 'Pelvic':
        img_data[img_data < -140] = -140
        img_data[img_data > 260] = 260
    elif window == 'Chest':
        img_data[img_data < -250] = -250
        img_data[img_data > 240] = 240
    elif window == 'Pelvic_scatter':
        img_data[img_data < -700] = -700
        img_data[img_data > 240] = 240
    else:
        img_data[img_data < 0] = 0
        img_data[img_data > 80] = 80
    return img_data

#读入dicom图像
dcm_path = 'E:/DeepLearningWorkSpace/PyCharmWorkSpace/date/CBCT_Pelvic/Pelvic-Reference-Data/CBCT/BuHui/01/20.dcm'
pixel_array, rows, columns, slice_location = read_dicom_data(dcm_path)
plt.subplot(131)
plt.title('Yuantu')
plt.imshow(pixel_array, cmap='gray')
pixel_array1 = pixel_array
pixel_array2 = pixel_array

pixel_array1 = window('Pelvic',pixel_array1)
imageData1 = (pixel_array1 - pixel_array1.min()) * 255.0 / (pixel_array1.max() - pixel_array1.min())
imageData1 = np.uint8(imageData1)
plt.subplot(132)
plt.title('window1')
plt.imshow(imageData1, cmap='gray')

pixel_array2 = window('Pelvic_scatter',pixel_array2)
imageData2 = (pixel_array2 - pixel_array2.min()) * 255.0 / (pixel_array2.max() - pixel_array2.min())
imageData2 = np.uint8(imageData2)
plt.subplot(133)
plt.title('window2')
plt.imshow(imageData2, cmap='gray')
plt.show()

 使用不同的窗宽出现相同的显示结果(第二幅和第三幅图),因为:

pixel_array1 = pixel_array
pixel_array2 = pixel_array

在这里拷贝的时候用了浅拷贝,改变pixel_array1的窗宽时pixel_array和pixel_array2都发生了改变,所以window2是在改变了的pixel_array的基础上进行的。但我们不希望发生这种变化,我们希望window2是在原图上改变,所以,可以改为将浅拷贝改为copy浅拷贝或者深拷贝。

pixel_array1 = copy.copy(pixel_array)
pixel_array2 = copy.copy(pixel_array)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值