首页 > 其他分享 >list 和 dict 的复制

list 和 dict 的复制

时间:2022-12-01 11:07:42浏览次数:42  
标签:可以 list 复制 dict copy 我们


list 和 dict 的复制_python




我们都知道,Python 中有两种可变的数据类型:list 和 dict。这两种数据类型对应的实例也有很多方法可以对自身进行修改,需要注意的是,这里调用修改相关的方法的时候不是返回修改后的实例,而是就地修改,也就是原地修改。我们有些时候不希望原来的被修改,因此,复制它们的实例就显得非常重要。



元素复制(针对 list)




我们都知道,一个 list 乘上一个整数 n 表示重复 list 中的元素 n 次创建一个新 list。这里需要注意的是 n ≥ 0,如果 n < 0,返回新的空 list(我也不知道为什么,记就完事了),不相信可以看下面的示例。

>>> [0, 1] * 2
[0, 1, 0, 1]
>>> [0, 1] * 1
[0, 1]
>>> [0, 1] * 0
[]
>>> [0, 1] * -1
[]
>>> [0, 1] * -2
[]

由此可以得出,创建 10 个元素全为 0 的 list 可以这么做:[0] * 10,我们来看看是不是彻底实现了复制。

>>> a = [0] * 10
>>> a
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
>>> a[0] = 1
>>> a
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0]

果然实现了复制,修改第一个元素的值对其余的元素没有影响。然而,事情可能没有那么简单,我们再来看一个例子。

>>> a = [[]] * 10
>>> a
[[], [], [], [], [], [], [], [], [], []]
>>> a[0].append(0)
>>> a
[[0], [0], [0], [0], [0], [0], [0], [0], [0], [0]]

我们可以发现,结果并不是我们想要的,一改全改。因此,我们发现乘法有些时候不能进行复制。与此同时,我们希望大 list 里面的小 list 也实现复制,而不是指向同一个,怎么做?很简单,使用列表推导式就可以了,还是这个例子。

>>> a = [[] for _ in range(10)]
>>> a
[[], [], [], [], [], [], [], [], [], []]
>>> a[0].append(0)
>>> a
[[0], [], [], [], [], [], [], [], [], []]

这下应该没有问题了,针对 list 的元素复制到此结束。如果进行元素复制怕遇到这样的麻烦就全部使用列表推导式。但是,乘法也要会,因为有些模块或者是项目的源码可能会使用乘法!


整体复制




讲完了元素复制,我们来看一下整体复制。因为整体复制针对 list 和 dict 都可以使用,所以我分成两部分进行讲解,先看 list 的整体复制,再看 dict 的整体复制。



list 整体复制



我们假设有一个 list 的实例 a,要把它复制给 b,我们能不能直接写 b = a 呢?其实是不行的,不信的话可以看一下下面的示例。

>>> a = [1, 2, 1]
>>> b = a
>>> b[2] = 3
>>> a
[1, 2, 3]

我们可以发现,修改 b 的时候,a 也跟着改了,因此我们可以看出 a 和 b 是同一个 list,如何让 a 和 b 只是值相等,但它们是不同的 list 呢?

最容易想到的方法就是使用 list 的方法 copy,还是这个例子。

>>> a = [1, 2, 1]
>>> b = a.copy()
>>> b[2] = 3
>>> a
[1, 2, 1]

我们可以发现修改 b 对 a 没有任何影响,因此完成了复制。

完成复制的操作其核心代码就是第二行,我们还可以使用下面几种方法来完成复制。

>>> b = a[:]
>>> b = list(a)
>>> b = [_ for _ in a]
>>> b = a + [] # 写成 b = [] + a 也可以
>>> b = a * 1 # 写成 b = 1 * a 也可以

其中后面两种可能不是那么容易能够想得到的,这些方法都能完成复制,大家可以自己进行验证,我就不做演示了。

但是,这几种复制的方法都存在一个问题,我拿使用 copy 方法进行复制来演示一下这个问题。

>>> a = [[], []]
>>> b = a.copy()
>>> b[0].append(0)
>>> a
[[0], []]

我们可以发现复制并没有那么彻底,我们把这种不彻底的复制称之为浅复制。那么,如何不让它进行所谓的浅复制?我们后面再说,先继续看 dict 的整体复制。



dict 整体复制



我们假设有一个 dict 的实例 a,要把它复制给 b,我们能不能直接写 b = a 呢?其实是不行的,不信的话可以看一下下面的示例。

>>> a = {'1': 1, '2': 2}
>>> b = a
>>> b['1'] = 0
>>> a
{'1': 0, '2': 2}

我们可以发现,当 b 修改对应键的值时,a 也跟着修改,因此我们可以看出 a 和 b 是同一个 dict,如何让 a 和 b 只是值相等,但它们是不同的 dict 呢?

最容易想到的方法就是使用 dict 的方法 copy,还是这个例子。

>>> a = {'1': 1, '2': 2}
>>> b = a.copy()
>>> b['1'] = 0
>>> a
{'1': 1, '2': 2}

我们可以发现修改 b 对 a 没有任何影响,因此完成了复制。

完成复制的操作其核心代码就是第二行,我们还可以使用下面几种方法来完成复制。

>>> b = dict(a)
>>> b = {k: a[k] for k in a}

但是,这几种复制的方法都存在一个问题,我拿使用 copy 方法进行复制来演示一下这个问题。

>>> a = {'1': [1], '2': [2]}
>>> b = a.copy()
>>> b['1'].append(1)
>>> a
{'1': [1, 1], '2': [2]}

我们可以发现这样的复制都是浅复制,如何不进行浅复制呢?答案很简单,进行深复制即可。


深复制




我首先来讲一下什么是深复制。深复制,即同时复制值及其包含的所有值,等等。大家看了这么专业的解释可能会觉得云里雾里,不过不用担心,我可以让大家彻底理解深复制,只要记住一句话就行:“深复制是彻底的复制!

深复制我们没有必要自己实现,Python 有模块已经给你实现好了,开箱即用就完事了。还是使用上面的例子进行演示。

>>> a = {'1': [1], '2': [2]}
>>> from copy import deepcopy
>>> b = deepcopy(a)
>>> b['1'].append(1)
>>> a
{'1': [1], '2': [2]}

同样的,对于 list 套 list 的情况也必须使用深复制。

当然,我从今年开始已经入驻 B 站了!下面给出 B 站账号:新时代的运筹帷幄,喜欢的可以关注一下,看完视频不要忘记一键三连啊!

今天的文章有不懂的可以后台回复“加群”,备注:Python 机器学习算法说书人,不备注可是会被拒绝的哦~!




list 和 dict 的复制_深复制_02

扫码关注



标签:可以,list,复制,dict,copy,我们
From: https://blog.51cto.com/u_15829940/5901360

相关文章

  • list、dict和set的综合应用:排课系统(2)
    差一点我们就擦肩而过了有趣有用有态度上回说到,我们主要实现了排课系统的后台数据的定义以及每个数据对象之间的关系,这一次我们就来批量增加一些数据,为了给后面的排课算法进......
  • list、dict和set的综合应用:排课系统(1)
    差一点我们就擦肩而过了有趣有用有态度我们都知道一个程序从本质上来说就是算法+数据结构,这次就以我的本科毕业设计——排课系统为例,专门讲解如何设计排课的算法和要用到的......
  • wpf Datagrid绑定 Dictionary
    原文网址: https://www.cnblogs.com/zany-hui/articles/7623874.html数据源格式:Dictionary<int,List<string>>1.通过xaml设置<DataGridx:Name="dg"ItemsSource="{Bi......
  • MFC--List列表控件
           ......
  • jeecgboot 数据字典下拉框j-dict-select-tag使用
    页面配置数据字典product_type后端@Dict(dicCode="product_type")privateStringtype;前端<j-dict-select-tagv-decorator="['type',validatorRules.type]"placeho......
  • springboot消息之@RabbitListener&@EnableRabbit监听消息队列的内容
    1-新建service包BookService类packagecom.example.springbootamqp.service;importcom.example.springbootamqp.bean.Book;importorg.springframework.amqp.rabbit......
  • C# List合并相同元素
     C#List合并相同元素,对相同属性的列进行求和原数据合并后     publicclassStudent{publicstring?Name{get;set;}pu......
  • LIstBox实现下拉列表
    1、初始化下拉列表DataTabledt=newDataTable();dt.Columns.Add("id");dt.Columns.Add("name");DataRowdr1=dt.NewRow()......
  • Java 集合框架2:List
    目录List1.概述2.功能拓展位置访问搜索迭代范围视图3.实现ArrayList实现原理CopyOnWriteArrayListLinkedList实现原理List1.概述List是一个有序序列,除了继承了Collect......
  • ArrayList源码
    //属性//默认初始大小privatestaticfinalintDEFAULT_CAPACITY=10;//空数组用这个privatestaticfinalObject[]EMPTY_ELEMENTDATA={};//扩展数组时用来和EM......