life is short i use python
1. Assignment
in Python,
The assignment of the object is to pass the object reference (memory address),
assignment (=),
is to create a new reference to the object,
Modifying any one of these variables will affect the other
will = ["Will", 28, ["Python", "C#", "JavaScript"]] wilber = will print('will>>', will, id(will)) print('wilber>>', wilber, id(wilber)) print('will elements of id>>', [id(ele) for ele in will]) print('wilber elements of id>>',[id(ele) for ele in wilber]) print('---'*30) will[0] = "Wilber" will[2].append("CSS") print('will>>', will, id(will)) print('wilber>>', wilber, id(wilber)) print('will elements of id>>', [id(ele) for ele in will]) print('wilber elements of id>>',[id(ele) for ele in wilber]) #output as will>> ['Will', 28, ['Python', 'C#', 'JavaScript']] 43988040 wilber>> ['Will', 28, ['Python', 'C#', 'JavaScript']] 43988040 will elements of id>> [31326928, 493056320, 43988808] wilber elements of id>> [31326928, 493056320, 43988808] ------------------------------------------------------------------------------------------ will>> ['Wilber', 28, ['Python', 'C#', 'JavaScript', 'CSS']] 43988040 wilber>> ['Wilber', 28, ['Python', 'C#', 'JavaScript', 'CSS']] 43988040 will elements of id>> [44016672, 493056320, 43988808] wilber elements of id>> [44016672, 493056320, 43988808]
Source code information e-book: Click here to jump to the end of the article to get the business card
Two, shallow copy
A shallow copy creates a new object,
In this example "wilber is not will" but,
For elements in an object,
Shallow copy will only use the reference (memory address) of the original element,
That is to say "wilber[i] is will[i]"
When modifying will:
Since the first element of the list is an immutable type,
So the first element of the list corresponding to will will use a new object 39758496;
But the third element of the list is a mutable type,
The modification operation will not generate a new object, so the modification result of will will be reflected on wilber accordingly
shallow copy:
Create a new object,
but what it contains is a reference to the item contained in the original object
(If one of the objects is modified by reference, the other will also be modified)
{1, full slice method; 2, factory function, such as list(); 3, copy() function of copy module}
Slices are also shallow copies
import copy will = ["Will", 28, ["Python", "C#", "JavaScript"]] wilber = copy.copy(will) print('will>> ', will, id(will)) print('wilber>> ', wilber, id(wilber)) print('will elements of id>> ', [id(ele) for ele in will]) print('wilber elements of id>>',[id(ele) for ele in wilber]) print('---'*30) will[0] = "Wilber" will[2].append("CSS") print('will>> ', will, id(will)) print('wilber>> ', wilber, id(wilber)) print('will elements of id>> ', [id(ele) for ele in will]) print('wilber elements of id>>',[id(ele) for ele in wilber]) will>> ['Will', 28, ['Python', 'C#', 'JavaScript']] 43862024 wilber>> ['Will', 28, ['Python', 'C#', 'JavaScript']] 43861896 will elements of id>> [31261392, 493056320, 43862088] wilber elements of id>> [31261392, 493056320, 43862088] ------------------------------------------------------------------------------------------ will>> ['Wilber', 28, ['Python', 'C#', 'JavaScript', 'CSS']] 43862024 wilber>> ['Will', 28, ['Python', 'C#', 'JavaScript', 'CSS']] 43861896 will elements of id>> [43886384, 493056320, 43862088] wilber elements of id>> [31261392, 493056320, 43862088]
3. Deep copy
Similar to shallow copy, deep copy also creates a new object,
In this example "wilber is not will" however,
For elements in an object,
Deep copy will regenerate a copy (there are special cases, which will be explained below),
Instead of simply using the reference (memory address) of the original element
Deep copy:
Create a new object,
and recursively copies the objects it contains
(Modify one of them, the other will not change)
{deep.deepcopy() function of the copy module}
import copy will = ["Will", 28, ["Python", "C#", "JavaScript"]] wilber = copy.deepcopy(will) print('will>> ', will, id(will)) print('wilber>> ', wilber, id(wilber)) print('will elements of id>> ', [id(ele) for ele in will]) print('wilber elements of id>>',[id(ele) for ele in wilber]) print('---'*30) will[0] = "Wilber" will[2].append("CSS") print('will>> ', will, id(will)) print('wilber>> ', wilber, id(wilber)) print('will elements of id>> ', [id(ele) for ele in will]) print('wilber elements of id>>',[id(ele) for ele in wilber]) # output as will>> ['Will', 28, ['Python', 'C#', 'JavaScript']] 37373960 wilber>> ['Will', 28, ['Python', 'C#', 'JavaScript']] 37373832 will elements of id>> [31195856, 493056320, 37374024] wilber elements of id>> [31195856, 493056320, 37373768] ------------------------------------------------------------------------------------------ will>> ['Wilber', 28, ['Python', 'C#', 'JavaScript', 'CSS']] 37373960 wilber>> ['Will', 28, ['Python', 'C#', 'JavaScript']] 37373832 will elements of id>> [37398264, 493056320, 37374024] wilber elements of id>> [31195856, 493056320, 37373768]
4. Special circumstances
For non-container types
(such as numbers, strings, and other 'atomic' types of objects)
no copy
That is to say,
For these types,
"obj is copy.copy(obj)" ,"obj is copy.deepcopy(obj)"
If the tuple variable only contains atomic type objects, it cannot be deep copied, see the following example
import copy books=('a','b','c') books1,books2 = copy.copy(books),copy.deepcopy(a) >>books is books1 is books2 # true a = 'python' b,c = copy.copy(a),copy.deepcopy(a) In [19]: a is b is c Out[19]: True In [20]: id(a),id(b),id(c) Out[20]: (55466056, 55466056, 55466056) In [30]: t1=('a','b','c',['d']) In [31]: t2,t3 = copy.copy(t1),copy.deepcopy(t1) In [32]: t1 is t2 is t3 Out[32]: False In [33]: id(t1), id(t2), id(t3) Out[33]: (89247560, 89247560, 88537672)
The assignment of objects in Python is all about object references (memory addresses)
transfer
use copy.copy(),
Shallow copies of objects can be made,
It copies the object, but for elements in the object,
Still use the original reference.
If you need to copy a container object,
and all elements inside it (children of the containing element),
You can use copy.deepcopy() to make a deep copy
For non-container types
(such as numbers, strings, and other 'atomic' types of objects)
not copied
If the tuple variable contains only atomic type objects, it cannot be deep copied
1. Example of a shallow copy of a list
import copy a = [1,2,3,4,['a','b']] #define a list a b = a #assignment c = copy.copy(a) #shallow copy d = copy.deepcopy(a) #deep copy a.append(5) a[0] = '10' print('A0',a,id(a)) # [1, 2, 3, 4, ['a', 'b'], 5] #a adds an element 5 print('B0',b,id(b)) # [1, 2, 3, 4, ['a', 'b'], 5] #b followed by adding an element 5 print('C0',c,id(c)) # [1, 2, 3, 4, ['a', 'b']] #c stays the same print('D0',d,id(d)) # [1, 2, 3, 4, ['a', 'b']] #d stays the same a[4].append('c') a[4][1]='ASDF' print('A1',a,id(a)) # [1, 2, 3, 4, ['a', 'b', 'c'], 5] #The list in a (that is, a[4]) adds an element c print('B1',b,id(a)) # [1, 2, 3, 4, ['a', 'b', 'c'], 5] #b followed by adding an element c print('C1',c,id(c)) # [1, 2, 3, 4, ['a', 'b', 'c']] #c followed by adding an element c print('D1',d,id(d)) [1, 2, 3, 4, ['a', 'b']] #d stays the same
2. copy of a single list
names = ['alex','jack','1','mack','racheal','shanshan'] n2 = names n3 = names.copy() n4 = names[:] print('first round','names',names,id(names)) print('first round','n2',n2,id(n2)) print('first round','n3',n3,id(n3)) print('first round','n4',n4,id(n4)) names.append('hery') names[0]="Alex" print('second round','names',names,id(names)) print('second round','n2',n2,id(n2)) print('second round','n3',n3,id(n3)) print('second round','n4',n4,id(n4))
output:
first round names ['alex', 'jack', '1', 'mack', 'racheal', 'shanshan'] 167690376 first round n2 ['alex', 'jack', '1', 'mack', 'racheal', 'shanshan'] 167690376 first round n3 ['alex', 'jack', '1', 'mack', 'racheal', 'shanshan'] 167692616 first round n4 ['alex', 'jack', '1', 'mack', 'racheal', 'shanshan'] 167713928 second round names ['Alex', 'jack', '1', 'mack', 'racheal', 'shanshan', 'hery'] 167690376 second round n2 ['Alex', 'jack', '1', 'mack', 'racheal', 'shanshan', 'hery'] 167690376 second round n3 ['alex', 'jack', '1', 'mack', 'racheal', 'shanshan'] 167692616 second round n4 ['alex', 'jack', '1', 'mack', 'racheal', 'shanshan'] 167713928
3. String copy
import copy name="hahah" #string name1=copy.copy(name) name2=copy.deepcopy(name) print('first',id(name),id(name1),id(name2)) sum=111 #number sum1=copy.copy(sum) sum2=copy.deepcopy(sum) print('the second time',id(sum),id(sum1),id(sum2))
output:
First time 31179752 31179752 31179752 Second time 1702001568 1702001568 1702001568
4. copy of the dictionary
import copy call = { 'cpu':[80,25], 'mem':[80,], 'disk':[80,] } new_call_1 = copy.copy(call) new_call_2 = copy.deepcopy(call) print('before fixing call1 for:%s' %(call),id(call)) # #modify new template call['disk'] = 66 call['disk_2'] = 67 call['cpu'].append(20) call['cpu'][1]=11 new_call_1['cpu'].append(33) new_call_1['disk'][0] = 77 new_call_1['mem'] = 75 new_call_2['disk'][0] = 79 # #View the values of old and new templates print('call1 for:%s' %(call),id(call)) print('new_call_1 for:%s' %(new_call_1),id(new_call_1)) print('new_call_2 for:%s' %(new_call_2),id(new_call_2))
output:
before fixing call1 for:{'cpu': [80, 25], 'mem': [80], 'disk': [80]} 4411328 call1 for:{'cpu': [80, 11, 20, 33], 'mem': [80], 'disk': 66, 'disk_2': 67} 4411328 new_call_1 for:{'cpu': [80, 11, 20, 33], 'mem': 75, 'disk': [77]} 4452424 new_call_2 for:{'cpu': [80, 25], 'mem': [80], 'disk': [79]} 31977616
Python print progress bar
import time for i in range(0,101,2): time.sleep(0.1) char_num = i//2 per_str = '\r%s%% : %s\n' % (i, '>>>' * char_num) if i == 100 else '\r%s%% : %s'%(i,'*'*char_num) print(per_str,end='', flush=True)