Lists and Dictionaries in Python 01

Since there is no systematic learning of python, sometimes it will go into the pit when using it. For example, writing code today encountered two problems:

  • In the method of the class, the member variable of the class is referenced to assign a value to the variable in the method, and this member variable is a dictionary type. It turns out that when the variable in the method is
    modified , the value of the member variable of the class is also modified.
class A(object):
  r={}
  def __init__(self):
    self.d = {"k":"aaa"}
  def A1(self):
    d2 = self.d
    d2['k'] = 'bbb'
if __name__ == "__main__":
  a = A()
  a.A1()
  print a.d     
'''
输出:{"k":"bbb"}
'''

As you can see, in fact, I just modified the variable d2 in the method, but the value of the member d has also been modified.

  • Add a dictionary to the list in the form of a variable, modify the value of the elements in the list, and the original dictionary is also changed
if __name__ == "__main__":
  d={'k':''}
  l = []
  l.append(d)
  l[0]['k'] = 'aaa'
  l.append(d)
  print d
  print l
'''
其实不仅是列表,变量赋值也一样:
d1 = {"k":""}
d2 = d1
d2["k"] = 123
print d1   #{"k",123}
'''
输出:
d={'k':'aaa'}
[{'k':'aaa'},{'k':'aaa'}]

You can see that I just modified the elements of the list, but the value of the dictionary has also changed.
After the second append(d), l[2] is not modified, but since d has changed, the value
of the added list l[1]['k']is no longer the
starting .

  • Through several sets of tests, it is found that lists and dictionaries are stored in the form of addresses at the bottom layer of python, and the use of the equal sign is equivalent to just doing
    a shallow copy, and the method of pointers is still used at the bottom layer, so deep copy can be used to solve the problem.

    关于深浅拷贝,简单的来说就是,在有指针的情况下,浅拷贝只是增加了一个指针指向已经存在的内存,而深拷贝就是增加一个指针并且申请一个新的内存,使这个增加的指针指向这个新的内存
    

    demo:

#!/usr/bin/env python
#-*- coding:utf-8 -*-
import copy

class A(object):
  r={}
  def __init__(self):
    self.x = 0
    self.l = []
    self.s = "sss"
    self.d = {"k":"aaa"}

  def A1(self):
    x2 = self.x
    x2 = 2    ##int数 x2 修改后 类的成员self.x不变

  def A3(self):
    s2 = self.s
    s2 = "abc" ##字符串 s2修改后 类的成员self.s不变

  def A2(self):
    l2 = self.l
    l2.append(self.x) ##列表 l2 修改后 类的成员self.s的值-->跟随l2改变
    l2[-1] = 2

  def A4(self):
    d2 = self.d
    r2 = self.r
    d2['k']="bbb"  ##字典 d2 修改后 类的成员self.d的值-->跟随d2改变
    r2['k']="bbb"  ##同上

  def A5(self):
    l2 = []
    x2 = 0
    s2 = ""
    l2.append(x2)   ## 以变量形式向列表添加 int数和字符串
    l2.append(s2)
    print "l2:",l2
    print "x2:", x2
    print "s2:",s2
    l2[0] = '123'   ## 修改列表中对应元素的值
    l2[1]= "bbb"
    print "l2:", l2
    print "x2:", x2  ## 原int数、字符串的值不变
    print "s2:", s2


  def A6(self):
    l2 = []
    l3 = []
    d3 = {'k':''}
    l2.append(d3)  ## 以变量形式向列表添加 列表和字典
    l2.append(l3)
    print "l2:",l2
    print "l3:", l3
    print "d3:",d3
    l2[0]['k'] = 'bbb'  ## 修改列表中对应元素的值
    l2[1].append("bbb")
    #--------------------------------------------------------
    # 这里用append()会使原列表l3变化,但如果是l2[1]=["bbb"]则不会
    # l2.append(l3)相当于将l2的末尾节点指向了l3内存空间,
    # 而l2[1].append("bbb")相当于向这个内存空间存储“bbb”,
    # l2[1] = ['bbb']则是将l2的末尾节点重定向到了['bbb']
    #--------------------------------------------------------
    print "l2:",l2
    print "l3:", l3    ##原列表、字典的值都变化,
    print "d3:",d3

  ### 字典的深拷贝
  def A_dep(self):
    print "self.d",self.d
    print "self.r",self.r
    d_cp = copy.copy(self.d)
    r_dpcp = copy.deepcopy(self.r)
    d_cp['k'] = 'ccc'
    r_dpcp['k'] = 'ccc'
    print "d_cp",d_cp
    print "r_dpcp",r_dpcp
    print "self.d",self.d    ##  使用两种深拷贝,在内存中重新开辟了空间,而不是指针指向的方式
    print "self.r",self.r

    ll = []
    ll2 = []
    ll.append(copy.copy(self.d))
    ll2.append(copy.deepcopy(self.r))
    ll[0]['k'] = "ccc"
    ll2[0]['k'] = "ccc"
    print "ll:",ll
    print "ll2:", ll2
    print "self.d", self.d  ## 以变量形式向列表添加字典,也是一样
    print "self.r", self.r


if __name__ == "__main__":
  a=A()
  print "___测试修改类中的成员:int数___"
  a.A1()
  print "self.x:",a.x
  print "___测试修改类中的成员:字符串___"
  a.A3()
  print "self.s:", a.s
  print "___测试修改类中的成员:列表___"
  a.A2()
  print "slef.l:",a.l
  print "self.x:",a.x
  print "___测试修改类中的成员:字典___"
  a.A4()
  print "self.d",a.d
  print "self.r",a.r
  print "___测试以变量方式向列表添加int数、字符串,然后修改列表中int数、字符串的值,原int数、字符串是否变化___"
  a.A5()
  print "___测试以变量方式向列表添加列表字典,然后修改列表中列表、字典元素的值,原列表、字典是否变化___"
  a.A6()
  print "___测试字典深拷贝____"
  a.A_dep()
'''
/usr/bin/python2.7 /home/zhanglu/PycharmProjects/log_parsing/test_01.py
___测试修改类中的成员:int数___
self.x: 0
___测试修改类中的成员:字符串___
self.s: sss
___测试修改类中的成员:列表___
slef.l: [2]
self.x: 0
___测试修改类中的成员:字典___
self.d {'k': 'bbb'}
self.r {'k': 'bbb'}
___测试以变量方式向列表添加int数、字符串,然后修改列表中int数、字符串的值,原int数、字符串是否变化___
l2: [0, '']
x2: 0
s2: 
l2: ['123', 'bbb']
x2: 0
s2: 
___测试以变量方式向列表添加列表字典,然后修改列表中列表、字典元素的值,原列表、字典是否变化___
l2: [{'k': ''}, []]
l3: []
d3: {'k': ''}
l2: [{'k': 'bbb'}, ['bbb']]
l3: ['bbb']
d3: {'k': 'bbb'}
___测试字典深拷贝____
self.d {'k': 'bbb'}
self.r {'k': 'bbb'}
d_cp {'k': 'ccc'}
r_dpcp {'k': 'ccc'}
self.d {'k': 'bbb'}
self.r {'k': 'bbb'}
ll: [{'k': 'ccc'}]
ll2: [{'k': 'ccc'}]
self.d {'k': 'bbb'}
self.r {'k': 'bbb'}

进程完成,退出码 0
'''

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325810552&siteId=291194637