zoukankan      html  css  js  c++  java
  • 3.python基础补充(集合,collection系列,深浅拷贝)

    一.集合

    1.集合(set):

    不同的元素组成一起形成集合,是python基本的数据类型。集合元素(set elements):组成集合的成员

    python的set和其他语言类似, 是一个无序不重复元素集, 基本功能包括关系测试和消除重复元素. 集合对象还支持union(联合), intersection(交), difference(差)和sysmmetric difference(对称差集)等数学运算.  

    sets 支持 x in set, len(set),和 for x in set。作为一个无序的集合,sets不记录元素位置或者插入点。因此,sets不支持 indexing, slicing, 或其它类序列(sequence-like)的操作。 

    2.集合的创建

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    se = set([11,22,33,44])
    print(se)
    {33, 11, 44, 22}
    print(type(se))
    <class 'set'>
    或者
    >>> se = {'liu','yao'}
    >>> se
    {'yao', 'liu'}
    >>> type(se)
    <class 'set'>

    集合的使用

    具体用法:

    1.add(添加元素)

    1
    2
    3
    >>> se.add('123')
    >>> se
    {'yao', 'liu', '123'}

    2.clear(清空集合)

    1
    2
    3
    >>> se.clear()
    >>> se
    set()

    3.copy(浅拷贝)

    1
    2
    3
    4
    >>> se_1 = {'liu','yao'}
    >>> se_2=se_1.copy()
    >>> se_2
    {'yao', 'liu'}

    4.difference差异比较

    1
    2
    3
    4
    5
    6
    7
    8
    >>> se_1 = {'liu','yao','shi','shei'}
    >>> se_2 = {'haode','shi','liu'}
    #取出se_2中在se_1所没有的元素
    >>> se_1.difference(se_2)
    {'yao', 'shei'}
    #取出se_1中在se_2所没有的元素
    >>> se_2.difference(se_1)
    {'haode'}

    5.difference_update差异更新

    1
    2
    3
    4
    5
    6
    7
    >>> se_1
    {'shi', 'yao', 'liu'}
    >>> se_2
    {'shi', 'liu', 'haode'}
    >>> se_1.difference_update(se_2)
    >>> se_1
    {'yao'}

    6.discard移除指定元素

    1
    2
    3
    4
    5
    >>> se_1
    {'shi', 'yao', 'shei', 'liu'}
    >>> se_1.discard('shei')
    >>> se_1
    {'shi', 'yao', 'liu'}

    7.intersection取交集并且建立新的集合

    1
    2
    3
    4
    >>> se_1={'liu','yao','shi','sha','bi'}
    >>> se_2={'liu','yao','shi','er','bi'}
    >>> se_1.intersection(se_2)
    {'liu', 'shi', 'yao', 'bi'}

    8.intersection_update取交集并且更新原来的集合

    1
    2
    3
    4
    5
    >>> se_1={'liu','yao','shi','sha','bi'}
    >>> se_2={'liu','yao','shi','er','bi'}
    >>> se_1.intersection_update(se_2)
    >>> se_1
    {'liu', 'shi', 'yao', 'bi'}

    9.isdisjoint判断没有交集,没有返回true,有返回false

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    >>> se_1={'liu','yao','shi','sha','bi'}
    >>> se_2={'liu','yao','shi','er','bi'}
    >>> se_1.isdisjoint(se_2)
    False
    >>> se_2.isdisjoint(se_1)
    False
    >>> se_1={'liu','yao'}
    >>> se_2={'liuu','yaoo'}
    >>> se_2.isdisjoint(se_1)
    True

    10.issubset判断是否为子集

    1
    2
    3
    4
    5
    >>> se_1 = {'liu','yao'}
    >>> se_2 = {'liu','yao','shabi'}
    #判断se_1是否为se_2的子集
    >>> se_1.issubset(se_2)
    True

    11.issuperset判断是否为父集

    1
    2
    3
    4
    5
    6
    7
    8
    9
    >>> se_1 = {'liu','yao'}
    >>> se_2 = {'liu','yao','shabi'}
    #判断se_1是否为se_2的父集
    >>> se_1.issuperset(se_2)
    False
    #判断se_2是否为se_1的父集
    >>> se_2.issuperset(se_1)
    True
    >>>

    12.pop移除集合元素

    1
    2
    3
    >>> se_1 = {'liu','yao','sha','bi'}
    >>> se_1.pop()
    'sha'

    13.remove删除指定元素集合

    1
    2
    3
    4
    5
    >>> se_1 = {'liu','yao','sha','bi'}
    >>> se_1.remove('bi')
    >>> se_1
    {'sha', 'liu', 'yao'}
    >>>

    14.symmetric_difference取两个集合的差集,并建立新的元素

    1
    2
    3
    4
    5
    6
    7
    >>> se_1 = {'liu','yao','sha','bi'}
    >>> se_2 = {'liu','yao','shabi'}
    >>> se_1.symmetric_difference(se_2)
    {'sha', 'shabi', 'bi'}
    >>> b=se_1.symmetric_difference(se_2)
    >>> b
    {'sha', 'shabi', 'bi'}

    15.symmetric_difference_update两个集合的差集,更新原来的集合对象

    1
    2
    3
    4
    5
    >>> se_1 = {'liu','yao','sha','bi'}
    >>> se_2 = {'liu','yao','shabi'}
    >>> se_1.symmetric_difference_update(se_2)
    >>> se_1
    {'sha', 'shabi', 'bi'}

    16.union并集

    1
    2
    3
    4
    5
    6
    >>> se_1
    {'sha', 'shabi', 'bi'}
    >>> se_2
    {'shabi', 'liu', 'yao'}
    >>> se_1.union(se_2)
    {'yao', 'sha', 'shabi', 'liu', 'bi'}

    17.update更新集合

    1
    2
    3
    4
    5
    >>> se_1
    {'sha', 'shabi', 'bi'}
    >>> se_1.update('liuyao')
    >>> se_1
    {'y', 'o', 'shabi', 'bi', 'u', 'i', 'sha', 'l', 'a'}

    案例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    old_dict = {
        "#1":{ 'hostname':'c1', 'cpu_count': 2, 'mem_capicity': 80 },
        "#2":{ 'hostname':'c1', 'cpu_count': 2, 'mem_capicity': 80 },
        "#3":{ 'hostname':'c1', 'cpu_count': 2, 'mem_capicity': 80 }
    }
    new_dict = {
        "#1":{ 'hostname':'c1', 'cpu_count': 2, 'mem_capicity': 800 },
        "#3":{ 'hostname':'c1', 'cpu_count': 2, 'mem_capicity': 80 },
        "#4":{ 'hostname':'c2', 'cpu_count': 2, 'mem_capicity': 80 }
    }
    #获取old_dict元素
    old = set(old_dict.keys())
    print(old)
    #获取new_dict元素
    new = set(new_dict.keys())
    print(new)
    #要更新的集合元素(交集)
    update_set = old.intersection(new)
    print(update_set)
    #获取要删除的集合元素(差集)
    delete_set = old.difference(new)
    print(delete_set)
    #获取要添加的集合元素()
    add_set = new.difference(update_set)
    print(add_set)

    二.collection系列

    collections模块自Python 2.4版本开始被引入,包含了dict、set、list、tuple以外的一些特殊的容器类型,分别是:

    OrderedDict类:排序字典,是字典的子类。引入自2.7。

    namedtuple()函数:命名元组,是一个工厂函数。引入自2.6。

    Counter类:为hashable对象计数,是字典的子类。引入自2.7。

    deque:双向队列。引入自2.4。

    defaultdict:使用工厂函数创建字典,使不用考虑缺失的字典键。引入自2.5。

    文档参见:http://docs.python.org/2/library/collections.html

    使用的时候需要用import导入collections模块

    1.计数器(counter

    Counter类的目的是用来跟踪值出现的次数。它是一个无序的容器类型,以字典的键值对形式存储,其中元素作为key,其计数作为value。计数值可以是任意的Interger(包括0和负数)。Counter类和其他语言的bags或multisets很相似。

    (1)创建

     创建一个空的Counter类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    import collections
    c = collections.Counter()# 创建一个空的Counter类
    print(c)
    c = collections.Counter('asdfghjjhgfdqwer')
    print(c)
    c = collections.Counter({'a': 4, 'b': 2})#从一个字典对象创建
    print(c)
    c = collections.Counter(a=4, b=2) # 从一组键值对创建
    print(c)

    结果:

    1
    2
    3
    4
    Counter()
    Counter({'d': 2, 'f': 2, 'h': 2, 'g': 2, 'j': 2, 's': 1, 'a': 1, 'r': 1, 'q': 1, 'e': 1, 'w': 1})
    Counter({'a': 4, 'b': 2})
    Counter({'a': 4, 'b': 2})

    (2).计数值的访问

    当所访问的键不存在时,返回0,而不是KeyError;否则返回它的计数。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    >>> import collections
    >>> c = collections.Counter('asdfgdsasdf')
    >>> c['a']
    2
    >>> c['h']
    0
    >>> c['s']
    3
    >>>

    (3).计数器的更新与减少

    1.update()更新

    1
    2
    3
    4
    5
    6
    >>> c
    Counter({'s': 3, 'd': 3, 'a': 2, 'f': 2, 'g': 1})
    >>> c = collections.Counter('update')
    >>> c.update('update')
    >>> c
    Counter({'a': 2, 'e': 2, 'd': 2, 'p': 2, 'u': 2, 't': 2})

    2.subtract()减少

    1
    2
    3
    4
    5
    6
    7
    >>> c = collections.Counter('subtract')
    >>> c
    Counter({'t': 2, 'a': 1, 'c': 1, 'b': 1, 's': 1, 'r': 1, 'u': 1})
    >>> c.subtract('subtract')
    >>> c
    Counter({'a': 0, 'c': 0, 'b': 0, 's': 0, 'r': 0, 'u': 0, 't': 0})
    >>>

    (4)键的删除

    当计数值为0时,并不意味着元素被删除,删除元素应当使用del

    1
    2
    3
    4
    5
    6
    7
    8
    >>> c = collections.Counter('abcdcba')
    >>> c['b']=0
    >>> c
    Counter({'a': 2, 'c': 2, 'd': 1, 'b': 0})
    >>> del c['a']
    >>> c
    Counter({'c': 2, 'd': 1, 'b': 0})
    >>>

    (5) 迭代器

    返回一个迭代器。元素被重复了多少次,在该迭代器中就包含多少个该元素。所有元素按照字母序排序,个数小于1的元素不被包含。

    1
    2
    3
    4
    >>> c = collections.Counter('abcdcba')
    >>> list(c.elements())
    ['a', 'a', 'c', 'c', 'b', 'b', 'd']
    >>>

    (5)most_common([n])

    返回一个TopN列表。如果n没有被指定,则返回所有元素。当多个元素计数值相同时,按照字母序排列。

    1
    2
    3
    >>> c = collections.Counter('abcdcba')
    >>> c.most_common()
    [('a', 2), ('c', 2), ('b', 2), ('d', 1)]

    (6)浅拷贝

    1
    2
    3
    4
    5
    6
    7
    >>> c = collections.Counter('abcdcba')
    >>> c
    Counter({'a': 2, 'c': 2, 'b': 2, 'd': 1})
    >>> cc=c.copy()
    >>> cc
    Counter({'a': 2, 'c': 2, 'b': 2, 'd': 1})
    >>>

    (7)算术与集合操作

    +、-、&、|操作也可以用于Counter。其中&和|操作分别返回两个Counter对象各元素的最小值和最大值。需要注意的是,得到的Counter对象将删除小于1的元素。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    >>> c = collections.Counter(a=3, b=1)
    >>> d = collections.Counter(a=1, b=2)
    >>> c+d
    Counter({'a': 4, 'b': 3})
    >>> c-d
    Counter({'a': 2})
    >>> c&d
    Counter({'a': 1, 'b': 1})
    >>> c|d
    Counter({'a': 3, 'b': 2})

    一些Counter类的常用操作,来源于Python官方文档

    1
    2
    3
    4
    5
    6
    7
    8
    9
    sum(c.values())  # 所有计数的总数
    c.clear()  # 重置Counter对象,注意不是删除
    list(c)  # 将c中的键转为列表
    set(c)  # 将c中的键转为set
    dict(c)  # 将c中的键值对转为字典
    c.items()  # 转为(elem, cnt)格式的列表
    Counter(dict(list_of_pairs))  # 从(elem, cnt)格式的列表转换为Counter类对象
    c.most_common()[:-n:-1# 取出计数最少的n个元素
    c += Counter()  # 移除0和负值

    2.有序字典(orderedDict )

    有序字典继承字典的一切属性,只是在顺序上是有序的。

    1
    2
    3
    4
    5
    6
    >>> import collections
    >>> info = collections.OrderedDict({'name':'liuyao','age':21})
    >>> info
    OrderedDict([('age', 21), ('name', 'liuyao')])
    >>> type(info)
    <class 'collections.OrderedDict'>
    1
    2
    3
    4
    5
    6
    7
    8
    import collections
    info = collections.OrderedDict(name='liuyao',age='21',job='IT')
    print (info)
    print (info.keys())
    print (info.values())
    OrderedDict([('age', '21'), ('name', 'liuyao'), ('job', 'IT')])
    odict_keys(['age', 'name', 'job'])
    odict_values(['21', 'liuyao', 'IT'])

    一些功能:

    (1).move_to_end将指定的键值对从开头移动到末尾。

    1
    2
    3
    4
    5
    >>> import collections
    >>> info = collections.OrderedDict(name='liuyao',age='21',job='IT')
    >>> info.move_to_end('name')
    >>> info
    OrderedDict([('age', '21'), ('job', 'IT'), ('name', 'liuyao')])

    (2).pop删除字典键值,返回删除的键值的values

    1
    2
    3
    4
    5
    6
    >>> info = collections.OrderedDict(name='liuyao',age='21',job='IT')
    >>> info.pop('job')
    'IT'
    >>> info
    OrderedDict([('age', '21'), ('name', 'liuyao')])
    >>>

    (3).clear清除有序字典的值

    1
    2
    3
    4
    >>> info = collections.OrderedDict(name='liuyao',age='21',job='IT')
    >>> info.clear()
    >>> info
    OrderedDict()
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    import collections
    info = collections.OrderedDict(name='liuyao',age='21',job='IT')
    print (info)
    print (info.keys())
    print (info.values())
    print (info.items())
    OrderedDict([('age', '21'), ('job', 'IT'), ('name', 'liuyao')])
    odict_keys(['age', 'job', 'name'])
    odict_values(['21', 'IT', 'liuyao'])
    odict_items([('age', '21'), ('job', 'IT'), ('name', 'liuyao')])

    3.默认字典(defaultdict) 

    这里的defaultdict(function_factory)构建的是一个类似dictionary的对象,其中keys的值,自行确定赋值,但是values的类型,是function_factory的类实例,而且具有默认值。比如default(int)则创建一个类似dictionary对象,里面任何的values都是int的实例,而且就算是一个不存在的key, d[key] 也有一个默认值,这个默认值是int()的默认值0.

    defaultdict是对字典的类型的补充,他默认给字典的值设置了一个类型。创建一个默认字典,value值类型为列表.dic = collections.defaultdict(list)

    例:

     

    1
    2
    3
    4
    5
    6
    7
    8
    import collections
    s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
     
    d = collections.defaultdict(list)
    for k, v in s:
        d[k].append(v)
     
    list(d.items())

    defaultdict可以接受一个内建函数list作为参数。其实呢,list()本身是内建函数,但是再经过更新后,python里面所有东西都是对象,所以list改编成了类,引入list的时候产生一个类的实例。

    1
    2
    3
    4
    5
    6
    7
    8
    import collections
    dic = collections.defaultdict(list)
    dic['k1']
    print (dic)
    print (dic.keys())
    print (dic.values())
    dic['k1'].append('v1')
    print (dic.values())

    一些具有的方法:

    1.copy拷贝

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    import collections
    dic = collections.defaultdict(list)
    dic['k1']
    dic['k1'].append('v1')
    print (dic)
    dic_1=dic.copy()
    print (dic_1)
    #结果
    defaultdict(<class 'list'>, {'k1': ['v1']})
    defaultdict(<class 'list'>, {'k1': ['v1']})

    4.可命名元组(namedtuple) 

    没有现成的类,用户需要自行创建相应的类

    1
    2
    3
    4
    5
    6
    7
    8
    import collections
    tu = collections.namedtuple('tu',['x','y','z'])  #创建一个类,类名为Point
    yao_tu = tu(11,22,33)
    print(yao_tu)
    print(yao_tu.x)  #直接通过命名元素去访问元组对应的元素,
    print(yao_tu[1])  #等同于上面这种方式,但是没有上面这种方式可读性强
    print(yao_tu.y)
    print(yao_tu.z)

    5.双向队列(deque)

    (1)创建一个队列

    1
    2
    3
    import collections
    que = collections.deque(['sb','liu','yao'])
    print (que)

    (2)追加元素到队列

    1
    2
    3
    4
    5
    6
    >>> que.append('wo')
    >>> que
    deque(['sb', 'liu', 'yao', 'wo'])
    >>> que.append(['ni','ta'])
    >>> que
    deque(['sb', 'liu', 'yao', 'wo', ['ni', 'ta']])

    (3)追加元素到队列左侧

    1
    2
    3
    >>> que.appendleft('zuo')
    >>> que
    deque(['zuo', 'sb', 'liu', 'yao', 'wo', ['ni', 'ta']])

    (4)统计元素个数

    1
    2
    3
    4
    5
    6
    >>> que.appendleft('zuo')
    >>> que
    deque(['zuo', 'sb', 'liu', 'yao', 'wo', ['ni', 'ta']])
    >>> que.appendleft('zuo')
    >>> que.count('zuo')
    2

    (4)清除

    1
    2
    3
    >>> que.clear()
    >>> que
    deque([])

    (5)extend扩展元素

    1
    2
    3
    4
    5
    6
    >>> que = collections.deque(['sb','liu','yao'])
    >>> que
    deque(['sb', 'liu', 'yao'])
    >>> que.extend(['a','b','c'])
    >>> que
    deque(['sb', 'liu', 'yao', 'a', 'b', 'c'])

    (6)extendleft从左侧扩展

    1
    2
    3
    4
    5
    >>> que
    deque(['sb', 'liu', 'yao', 'a', 'b', 'c', 'zuo1', 'zuo2', 'zuo3'])
    >>> que.extendleft(['zuo4','zuo5','zuo6'])
    >>> que
    deque(['zuo6', 'zuo5', 'zuo4', 'sb', 'liu', 'yao', 'a', 'b', 'c', 'zuo1', 'zuo2', 'zuo3'])

    (7)pop删除

    1
    2
    3
    4
    5
    6
    >>> que
    deque(['zuo6', 'zuo5', 'zuo4', 'sb', 'liu', 'yao', 'a', 'b', 'c', 'zuo1', 'zuo2', 'zuo3'])
    >>> que.pop()
    'zuo3'
    >>> que
    deque(['zuo6', 'zuo5', 'zuo4', 'sb', 'liu', 'yao', 'a', 'b', 'c', 'zuo1', 'zuo2'])

    (8)popleft从左侧开始删除

    1
    2
    3
    4
    5
    6
    >>> que
    deque(['zuo6', 'zuo5', 'zuo4', 'sb', 'liu', 'yao', 'a', 'b', 'c', 'zuo1', 'zuo2'])
    >>> que.popleft()
    'zuo6'
    >>> que
    deque(['zuo5', 'zuo4', 'sb', 'liu', 'yao', 'a', 'b', 'c', 'zuo1', 'zuo2'])

    (9)reverse顺序反转

    1
    2
    3
    4
    5
    >>> que
    deque(['zuo5', 'zuo4', 'sb', 'liu', 'yao', 'a', 'b', 'c', 'zuo1', 'zuo2'])
    >>> que.reverse()
    >>> que
    deque(['zuo2', 'zuo1', 'c', 'b', 'a', 'yao', 'liu', 'sb', 'zuo4', 'zuo5'])

    (10)remove删除指定元素

    1
    2
    3
    4
    5
    >>> que
    deque(['zuo2', 'zuo1', 'c', 'b', 'a', 'yao', 'liu', 'sb', 'zuo4', 'zuo5'])
    >>> que.remove('sb')
    >>> que
    deque(['zuo2', 'zuo1', 'c', 'b', 'a', 'yao', 'liu', 'zuo4', 'zuo5'])

    (11)rotate将队列末尾4个元素反转到队列左侧

    1
    2
    3
    4
    5
    >>> que
    deque(['zuo5', 'zuo2', 'zuo1', 'c', 'b', 'a', 'yao', 'liu', 'zuo4'])
    >>> que.rotate(4)
    >>> que
    deque(['a', 'yao', 'liu', 'zuo4', 'zuo5', 'zuo2', 'zuo1', 'c', 'b'])

    6.单向队列 queue(先进先出 FIFO )

    (1)创建

    1
    2
    3
    4
    5
    6
    >>> import queue
    >>> que = queue.Queue(2)
    >>> que
    <queue.Queue object at 0x7f70678ec550>
    >>>
    >>> que = queue.Queue(maxsize=10)

    queue.Queue类即是一个队列的同步实现。队列长度可为无限或者有限。可通过Queue的构造函数的可选参数maxsize来设定队列长度。如果maxsize小于1就表示队列长度无限。

    (3)放入任务

     

    1
    2
    >>> que.put(['a','d'])
    >>> que

    调用队列对象的put()方法在队尾插入一个项目。put()有两个参数,第一个item为必需的,为插入项目的值;第二个block为可选参数,默认为
    1。如果队列当前为空且block为1,put()方法就使调用线程暂停,直到空出一个数据单元。如果block为0,put方法将引发Full异常。

    (3)从队列中取值

    1
    2
    3
    4
    >>> que.put(['a','d'])
    >>> que.get()
    ['a', 'd']
    >>>

    调用队列对象的get()方法从队头删除并返回一个项目。可选参数为block,默认为True。如果队列为空且block为True,get()就使调用线程暂停,直至有项目可用。如果队列为空且block为False,队列将引发Empty异常。

    (3)返回队列大小

    1
    2
    >>> que.qsize()
    1

    (4)判断队列为空返回True,反之False

    1
    2
    3
    >>> que.empty()
    False
    >>>

    (5)q.full() 如果队列满了,返回True,反之False

    1
    2
    3
    >>> que.full()
    False
    >>>

    q.full 与 maxsize 大小对应

    其他方法:

    1
    2
    3
    4
    5
    6
    q.get([block[, timeout]]) 获取队列,timeout等待时间
    q.get_nowait() 相当q.get(False)
    非阻塞 q.put(item) 写入队列,timeout等待时间
    q.put_nowait(item) 相当q.put(item, False)
    q.task_done() 在完成一项工作之后,q.task_done() 函数向任务已经完成的队列发送一个信号
    q.join() 实际上意味着等到队列为空,再执行别的操作

    三.深浅拷贝

    1.为什么要拷贝?

    当进行修改时,想要保留原来的数据和修改后的数据

    2.数字字符串 和 集合 在修改时的差异? (深浅拷贝不同的终极原因)

    在修改数据时:
        数字字符串:在内存中新建一份数据
             集合:修改内存中的同一份数据

    3.对于集合,如何保留其修改前和修改后的数据?

     在内存中拷贝

    4.对于集合,如何拷贝其n层元素同时拷贝?

    深拷贝

     


    1.对于 数字 和 字符串 而言,赋值、浅拷贝和深拷贝无意义,因为其永远指向同一个内存地址。

    例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    赋值,内存指向同一地址
    >>> n1=123
    >>> n2=n1
    >>> id(n1)
    10109728
    >>> id(n2)
    10109728
    >>>
    >>> import copy
    >>> n3 = copy.copy(n1)
    >>> id(n3)
    10109728
    >>> n4=copy.deepcopy(n1)
    >>> id(n4)
    10109728
    >>>

    2.对于字典、元祖、列表 而言,进行赋值、浅拷贝和深拷贝时,其内存地址的变化是不同的。

    赋值,只是创建一个变量,该变量指向原来内存地址,如:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    >>> import copy
    >>> n1 = {'k1':'v1','k2':'v2','k3':['liuyao','job']}
    >>> n1
    {'k3': ['liuyao', 'job'], 'k1': 'v1', 'k2': 'v2'}
    >>> n2=n1
    >>> id(n1)
    140120750514696
    >>> id(n2)
    140120750514696
    >>> id(n2['k3'])
    140120750335688
    >>> id(n1['k3'])
    140120750335688
    >>> id(n1['k3'][0])
    140120778934064
    >>> id(n2['k3'][0])
    140120778934064
    >>>

    (3)浅拷贝,在内存中只额外创建第一层数据

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    >>> import copy
    >>> n1 = {'k1':'v1','k2':'v2','k3':['liuyao','job']}
    >>> n2 = copy.copy(n1)
    >>> id(n1)
    140120750337544
    >>> id(n2)
    140120750371208
    >>> id(n1['k3'][0])
    140120778934064
    >>> id(n2['k3'][0])
    140120778934064
    >>>

    (4)深拷贝,在内存中将所有的数据重新创建一份(排除最后一层,即:python内部对字符串和数字的优化)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    >>> import copy
    >>> n1 = {'k1':'v1','k2':'v2','k3':['liuyao','job']}
    >>> n2 = copy.deepcopy(n1)
    >>> id(n1)
    140120750514696
    >>> id(n2)
    140120750514888
    >>> id(n1['k3'])
    140120750335688
    >>> id(n2['k3'])
    140120750335752
    >>> id(n2['k3'][0])
    140120778934064
    >>> id(n1['k3'][0])
    140120778934064
    >>>

    案例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    #深浅copy案例:监控模板
    dic = {
        "cpu":[80,],
        "mem":[70,],
        "disk":[90,],
     
    }
    print(dic)
    a1=copy.copy(dic)
    #浅copy会使所有的模板cpu都发生变化
    a1['cpu'][0]=20
    print(a1)
    print(dic)
    #为了防止新模板修改导致旧模板被修改所以使用深copy
    a2=copy.deepcopy(dic)
    a2['cpu'][0]=20
    print(a2)
    print(dic)





  • 相关阅读:
    CODING x 百果园 _ 水果零售龙头迈出 DevOps 体系建设第一步
    Nocalhost 亮相 CD Foundation 国内首届 Meetup,Keith Chan 将出席致辞
    做云原生时代标准化工具,实现高效云上研发工作流
    打造数字化软件工厂 —— 一站式 DevOps 平台全景解读
    WePack —— 助力企业渐进式 DevOps 转型
    CODING Compass —— 打造行云流水般的软件工厂
    Nocalhost —— 让云原生开发回归原始而又简单
    CODING 代码资产安全系列之 —— 构建全链路安全能力,守护代码资产安全
    Nocalhost:云原生开发新体验
    使用 Nocalhost 开发 Kubernetes 中的 APISIX Ingress Controller
  • 原文地址:https://www.cnblogs.com/liu-yao/p/5146505.html
Copyright © 2011-2022 走看看