The Python identifier, alias and equality
1.is,id和==
>>> charles = {'name': 'Charles L. Dodgson', 'born': 1832}
>>> lewis = charles ➊
>>> lewis is charles
True
>>> id(charles), id(lewis) ➋
(4300473992, 4300473992)
>>> lewis['balance'] = 950 ➌
>>> charles
{'name': 'Charles L. Dodgson', 'balance': 950, 'born': 1832}
Description: Every variable identifier, type, and value. Once an object is created, its identity never become; you can identify understood as the address of the object in memory. Identification is operator compares two objects; ID () function returns the object ID integer representation. id () Returns the object memory address, ID values must be unique label, and never become the object lifecycle. Programming is rarely used id () function. The most commonly used operator identity is checked, rather than direct comparison ID.
And the similarities and differences between is: Operator compares the value of two objects (the object data stored), the identification is an object of comparison.
2. The relatively non-denaturing tuple
Python tuple with most collections (lists, dictionaries, sets, etc.), as preservation is referenced object. If the reference element is variable, even if the tuple itself immutable elements still variable. That is, the tuple immutability actually refers to the physical structure of the data tuple contents (i.e., stored reference) is not changed, regardless of the object reference. And str, bytes, etc., and a single type of sequence array.array are flat, they are stored is not a reference, but the data itself is stored (characters, and numbers of bytes) in a continuous memory.
>>> t1 = (1, 2, [30, 40]) ➊
>>> t2 = (1, 2, [30, 40]) ➋
>>> t1 == t2 ➌
True
>>> id(t1[-1]) ➍
4302515784
>>> t1[-1].append(99) ➎
>>> t1
(1, 2, [30, 40, 99])
>>> id(t1[-1]) ➏
4302515784
>>> t1 == t2 ➐
False
3. The default do a shallow copy
>>> l1 = [3, [55, 44], (7, 8, 9)]
>>> l2 = list(l1) ➊
>>> l2
[3, [55, 44], (7, 8, 9)]
>>> l2 == l1 ➋
True
>>> l2 is l1 ➌
False
4. When tuple contains a list of copy and modify
l1 = [3, [66, 55, 44], (7, 8, 9)]
l2 = list(l1) # ➊
l1.append(100) # ➋
l1[1].remove(55) # ➌
print('l1:', l1)
print('l2:', l2)
l2[1] += [33, 22] # ➍
l2[2] += (10, 11) # ➎
print('l1:', l1)
print('l2:', l2)
Output:
l1: [3, [66, 44], (7, 8, 9), 100]
l2: [3, [66, 44], (7, 8, 9)]
l1: [3, [66, 44, 33, 22], (7, 8, 9), 100]
l2: [3, [66, 44, 33, 22], (7, 8, 9, 10, 11)]
Use http://www.pythontutor.com/visualize.html drawing program is running:
step1:
step2:
step3:
step4:
step5:
It can be simple but is not standardized summary: when changing the mutable object in the tuple, the actual change is referenced when changing immutable tuple, change the contents of a single object.
Therefore, the shallow copy operation is easy, but the results are probably not what you want
The shallow and deep copy replication
deepcopy copy and copy module functions can be provided so deep and shallow copy is a copy of any objects.
class Bus:
def __init__(self, passengers=None):
if passengers is None:
self.passengers = []
else:
self.passengers = list(passengers)
def pick(self, name):
self.passengers.append(name)
def drop(self, name):
self.passengers.remove(name)
>>> import copy
>>> bus1 = Bus(['Alice', 'Bill', 'Claire', 'David'])
>>> bus2 = copy.copy(bus1)
>>> bus3 = copy.deepcopy(bus1)
>>> id(bus1), id(bus2), id(bus3)
(4301498296, 4301499416, 4301499752)
>>> bus1.drop('Bill')
>>> bus2.passengers
['Alice', 'Claire', 'David']
>>> id(bus1.passengers), id(bus2.passengers), id(bus3.passengers)
(4302658568, 4302658568, 4302657800)
>>> bus3.passengers
['Alice', 'Bill', 'Claire', 'David']