zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    struts2文件上传下载
    struts2自定义拦截器
    JSP_Servlet 解决中文乱码登录问题
    ajax提交form表单
    sql语句大全
    spring
    struts2
    jsp_servlet
    jsp_servlet2
    数据库
  • 原文地址:https://www.cnblogs.com/colin1314/p/9457912.html
Copyright © 2011-2022 走看看