zoukankan      html  css  js  c++  java
  • python学习笔记4:基础(集合,collection系列,深浅拷贝)

    转载至:http://www.cnblogs.com/liu-yao/p/5146505.html

    一.集合

    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)
  • 相关阅读:
    拉格朗日乘数法
    线性判别分析(Linear Discriminant Analysis)
    有监督学习 和 无监督学习
    Jenkins入门知识
    vs技巧总结
    jenkins 神奇变量
    ubuntu12.04 折腾流水
    ubuntu 12.04 右上角的网络连接图标突然消失不见
    ubuntu 12.04 上网体验
    JIRA 初体验
  • 原文地址:https://www.cnblogs.com/xiongli/p/5793608.html
Copyright © 2011-2022 走看看