python深浅拷贝,集合以及数据类型的补充

1.基础数据类型的补充

1.元组

如果元组中只有一个数据,且没有逗号,则该‘元组’与里面的数据的类型相同。如:

1 tu = (1)
2 tu1 = (1,)
3 tu2 = (‘alex‘)
4 tu3 = ([1,2,3],)
5 print(tu,type(tu))    # 1 <class ‘int‘>
6 print(tu1,type(tu1))  # (1,) <class ‘tuple‘>
7 print(tu2,type(tu2))  # alex <class ‘str‘>
8 print(tu3,type(tu3))  # ([1, 2, 3],) <class ‘tuple‘>

2. 列表

列表与列表是可以相加的,如:

1 l1 = [1,2,3]
2 l2 = [‘alex‘,‘wusir‘]
3 l3 = l1 + l2  # [1, 2, 3, ‘alex‘, ‘wusir‘]
4 print(l3)

如何将列表中的索引为奇数的元素删除,如例题:  l1 = [11, 22, 33, 44, 55, 66, 77, 88]

1 l1 = [11, 22, 33, 44, 55, 66, 77, 88]
2 for i in range(len(l1)):
3     if i % 2 == 1:
4         l1.pop(i)
5 print(l1)      # IndexError: pop index out of range

上面的代码看似正确,但执行后却报错,报错解释为:

IndexError: pop index out of range

经过分析后可知,每当pop()一次后,将奇数位删除,此时,删除位之后的元素会向前移动一位,导致l1的索引会不断的发生变化。因此,本文提出了三种解决方法:

第一种:切片 + 步长删除

1 l1 = [11, 22, 33, 44, 55, 66, 77, 88]
2 del l1[1::2]
3 print(l1)

第二种方法:

1 l1 = [11, 22, 33, 44, 55, 66, 77, 88]
2 l2 = []    # 重新创建一个空列表
3 for i in range(len(l1)):
4     if i % 2 == 0:
5         l2.append(l1[i])
6 l1 = l2   # 用l2去覆盖l1
7 print(l1)

第三种方法:按照倒序删除:

1 for index in range(len(l1)-1, -1, -1):
2     if index % 2 == 1:
3         l1.pop(index)
4 print(l1)

综上分析:在循环一个列表时,最好不要对此列表直接进行改变大小(增删)操作。

3. 字典

字典的创建方式(三种:面试常考)

1 #1,
2 dic = {‘name‘:‘alex‘}
3 #2
4 dic = dict({‘name‘:‘alex‘})
5 print(dic)
6 #3, fromkeys()
7 dic1 = dict.fromkeys([1,2,3],‘alex‘)
8 print(dic1)

但是,在第三种创建方式下,有别于第一种和第二种方式:

1 dic1 = dict.fromkeys([1,2,3],[])
2 print(dic1)     # {1: [], 2: [], 3: []}
3 dic1[1].append(‘alex‘)
4 print(dic1)      # {1: [‘alex‘], 2: [‘alex‘], 3: [‘alex‘]}
5 print(id(dic1[1]))   # 1478241524744
6 print(id(dic1[2]))   # 1478241524744
7 print(id(dic1[3]))   # 1478241524744

如何将字典的键中含有k元素的所有键值对删除。如例题:dic = {‘key1‘: ‘value1‘,‘key2‘: ‘value2‘, ‘k3‘:‘v3‘, ‘name‘: ‘alex‘}

如果按照下面这种方式去处理会得到如下结果:

1 dic = {‘key1‘: ‘value1‘,‘key2‘: ‘value2‘, ‘k3‘:‘v3‘, ‘name‘: ‘alex‘}
2 for key in dic:
3     if ‘k‘ in key:
4         dic.pop(key)
5 print(dic)

运行代码时,会发生报错,报错解释为:dictionary changed size during iteration。

其分析结果与列表分析一样,这是由于在循环一个字典时,不能改变字典的大小。因此解决方案是可以创建一个新的列表,先用来存储需要删除的键,然后通过遍历这个列表,去删除原字典中对应有的键。解题如下:

1 dic = {‘key1‘: ‘value1‘,‘key2‘: ‘value2‘, ‘k3‘:‘v3‘, ‘name‘: ‘alex‘}
2 l1 = []
3 for key in dic:
4     if ‘k‘ in key:
5         l1.append(key)
6 # print(l1)
7 for key in l1:
8     dic.pop(key)
9 print(dic)

2.集合

集合是无序的,不重复的数据集合,它里面的元素是可哈希的(不可变类型),但是集合本身是不可哈希(所以集合做不了字典的键)的。

集合元素的数据类型通常为:元组,整数,字符串,bool值等。

集合的创建方式,有两种:

1 set1 = {‘alex‘, [1,2], 1,2,3}
2 set1 = {‘alex‘, ‘wusir‘}
3 set2 = set({‘alex‘, ‘wusir‘})
4 print(set2)

如何用list去重操作(面试题常考):

1 l1 = [1,1,2,3,4,4,3,2,1,5,5]
2 set1 = set(l1)
3 l2 = list(set1)
4 print(l2)

不可变数据类型:

1 set1 = {1,2,3}
2 set3 = frozenset(set1)
3 print(set3)  # 不可变的数据类型。  ***

3 深浅拷贝

1 浅拷贝

什么是浅拷贝???我们先来看一个例题:

1 # 列表只有一层,无嵌套情况
2 l1 = [1,2,3]
3 l2 = l1
4 l1.append(666)
5 print(l2)
6 print(id(l1))   # 2309663104392
7 print(id(l2))   # 2309663104392
1 # 有内层嵌套的列表
2 l1 = [1,2,3,[22,]]
3 l2 = l1.copy()
4 l1[-1].append(‘taibai‘)
5 print(l1,l2)   # [1, 2, 3, [22, ‘taibai‘]] [1, 2, 3, [22, ‘taibai‘]]
6 print(id(l1))   # 1787284757960
7 print(id(l2))   # 1787285576712
8 print(id(l1[-1]))   # 1787284757896
9 print(id(l2[-1]))   # 1787284757896

从上面的分析可以看出,对于浅copy来说,第一层创建的是新的内存地址,而从第二层开始,指向的都是同一个内存地址,所以,对于第二层以及更深的层数来说,保持一致性。

2.深拷贝

同样,先举一个例子来看看什么是深拷贝:

1 import copy
2 l1 = [1,2,3,[22,]]
3 l2 = copy.deepcopy(l1)
4 l1[-1].append(‘太白‘)
5 print(l1,l2)   # [1, 2, 3, [22, ‘太白‘]] [1, 2, 3, [22]]
6 print(id(l1))   # 1763810759304
7 print(id(l2))   # 1763810760584
8 print(id(l1[-1]))   # 1763810759112
9 print(id(l2[-1]))   # 1763810760520

从上面的分析我们可以知道:对于深copy来说,两个是完全独立的,改变任意一个的任何元素(无论多少层),另一个绝对不改变。

深浅拷贝应用的场景:面试常考,让你解释深浅拷贝。

# 完全独立的copy一份数据,与原数据没有关系,深copy

    # 如果一份数据(列表)第二层时,你想与原数据进行公用,浅copy。

另外:切片也属于浅拷贝,例如:

1 l1 = [1,2,3,[22,33]]
2 l2 = l1[:]
3 l1[-1].append(666)
4 print(l1,l2)   # [1, 2, 3, [22, 33, 666]] [1, 2, 3, [22, 33, 666]]
5 print(id(l1))   # 1234866347400
6 print(id(l2))   # 1234867166216
7 print(id(l1[-1]))   # 1234866347464
8 print(id(l2[-1]))   # 1234866347464

原文地址:https://www.cnblogs.com/colin1314/p/9457912.html

时间: 2024-10-09 19:51:45

python深浅拷贝,集合以及数据类型的补充的相关文章

8.6(数据类型分类,python深浅拷贝,异常处理,基本的文件操作,绝对路径和相对路径)

数据类型分类 按照存值个数: 存一个值:整型/浮点型/字符串 存多个值:列表/字典/元组/集合 按照有序和无序: 有序:字符串/列表/元组 无序:字典/集合 按照可变和不可变 可变:字典/列表/集合 不可变:整型/浮点型/字符串/元组 Python深浅拷贝 # 拷贝 赋值 # lt = [1,2,3] # lt2 = lt # lt.append(4) # print(lt) # print(lt2) # 列表为可变类型,所以lt的值变化,lt2的值也会跟着变化 # 浅拷贝 # import..

python 深浅拷贝 进阶

主要理解新与旧到底在哪里 这样也就理解了 深浅拷贝 先说说赋值,其实python中的赋值其实是赋值了一个引用,例如: foo1=1.0 foo2=foo1 用操作符is判断时,你可以发现结果是true,是因为python是先创建了一个对象1.0,然后这个对象的引用又被赋值给了foo1和foo2,但是如果是这样: foo1=1.0 foo2=1.0 这时你会发现,这其实是创建了两个不同的对象,用内建函数id()可以发现,二者的身份不同: 其实python还有一个特例,例如: a=1 b=1 你会发

Python开发【第二章】:Python深浅拷贝剖析

Python深浅拷贝剖析 Python中,对象的赋值,拷贝(深/浅拷贝)之间是有差异的,如果使用的时候不注意,就可能产生意外的结果. 下面本文就通过简单的例子介绍一下这些概念之间的差别. 一.对象赋值 创建列表变量Alex,变量包含子列表,通过变量Alex给变量lzl赋值,对

小数据池 深浅拷贝 集合

小数据池 小数据池 ---- 缓存机制(驻留机制) == 判断两边的内容是否相等 a = 10 b = 10 print(a == b) # True is 判断两边的值内存地址是否相等 a = 10 b = 10 print(a is b) # True print(id(a)) print(id(b)) #True 4329728336 地址是一样的 小数据池的数据范围: -5 ~ 256 a = -5 b = -5 c = -5 print(id(a)) print(id(b)) prin

Python深浅拷贝

深浅拷贝 深浅拷贝分为两部分,一部分是数字和字符串另一部分是列表.元组.字典等其他数据类型. 数字和字符串 对于数字和字符串而言,赋值.浅拷贝和深拷贝无意义,因为他们的值永远都会指向同一个内存地址. # 导入copy模块>>> import copy# 定义一个变量var1>>> var1 = 123# 输出var1的内存地址>>> id(var1)1347747440>>> var2 = var1# var2的内存地址和var1相同

Python 深浅拷贝 (Shallow copy and Deep copy in Python)

前言 昨天刷公众号看到一篇描述py优雅语法的文章,心痒之下到家就开始尝试,学习了for else statement,yield和py版三目写法.在列表切片这部分中,对作者的列表拷贝写法,有些不太理解. # 拷贝 copy_items = items[::] 或者 items[:] 尝试 首先开一个python,随便建一个列表l=[1,2,3]将其进行两种方法的拷贝: 我的写法 c=l 作者的写法 d=l[:] 分别打印了c和d,并没有什么差别,仔细斟酌了一下作者的用意,觉得应该有一些深层次的考

python深浅拷贝的理解和区分

1 import copy 2 3 a1 = ['s1','s2','s3'] 4 5 #可变数据类型 6 a = [1,2,a1] 7 8 b = a 9 a1.append('s4') 10 #浅拷贝 11 c = copy.copy(a) 12 #深拷贝 13 d = copy.deepcopy(a) 14 15 #可变数据类型打印 16 print('值打印----:') 17 print(a1) 18 print(a) 19 print(b) 20 print(c) 21 print(

python深浅拷贝以及数据在内存中储存方法

要搞懂深浅拷贝,首先要明白数据在内存里的储存方法. 一个变量的储存,首先是变量名加上储存内容的ID,通过ID去找到变量名所对应的内容, 当我们对数据进行赋值时,其实是把内容的整体地址赋给别的变量名(相当于复制一层ID) 然而当使用浅copy时,相当于把整体内容的地址与内容中第一层地址给复制(相当于复制两层ID) 应用:直接在变量名后加一个.copy(),或import调用copy模块使用模块中的方法copy.copy() 深度拷贝,其实是复制的整体以及整体内的所有ID(复制所有层ID) 方法是用

python 深浅拷贝

先定义一个列表 >>> s = [1,'alex','alvin'] >>> s2 = s.copy() 使用copy()方法拷贝,创建一个新的对象s2 >>> print(s2) 拷贝之后s2对象和s对象的内容一样. [1,'alex','alvin'] >>> s2[0] = 3 修改s2对象的值 >>> print(s2) [3,'alex','alvin'] 打印s2,发现s2对象的值发生了变化 >&g