Question 1: Pay attention to nested data types that are inserted into mutable types
Look at a piece of code
if __name__ == '__main__':
tx1 = {'from': 'Jason', 'to': 'Karmen'}
tx2 = {'from': 'Jason', 'to': 'Karmen'}
# id(txs[0]) = id(tx1) & id(txs[1]) = id(tx2)
txs = [tx1, tx2]
# [{'to': 'Karmen', 'from': 'Jason'}, {'to': 'Karmen', 'from': 'Jason'}]
print txs
# 往tx1新增一个键,txs也会更新
tx1['?'] = '?'
tx1['from'] = 'God'
# [{'to': 'Karmen', 'from': 'God', '?': '?'}, {'to': 'Karmen', 'from': 'Jason'}]
print txs
mylist = []
# id(mylist[0]) = id(tx1)
mylist.append(tx1)
mylist[0]['from'] = 'SKY'
# [{'to': 'Karmen', 'from': 'SKY', '?': '?'}, {'to': 'Karmen', 'from': 'Jason'}]
print txs
# [{'to': 'Karmen', 'from': 'SKY', '?': '?'}]
print mylist
# id(mylist[0]) = id(mylist[1]) = id(tx1)
mylist.append(tx1)
mylist[1]['to'] = 'RAINBOW'
# [{'to': 'RAINBOW', 'from': 'SKY', '?': '?'}, {'to': 'Karmen', 'from': 'Jason'}]
print txs
# [{'to': 'RAINBOW', 'from': 'SKY', '?': '?'}, {'to': 'RAINBOW', 'from': 'SKY', '?': '?'}]
print mylist
The result is:
[{'to': 'Karmen', 'from': 'Jason'}, {'to': 'Karmen', 'from': 'Jason'}]
[{'to': 'Karmen', 'from': 'God', '?': '?'}, {'to': 'Karmen', 'from': 'Jason'}]
[{'to': 'Karmen', 'from': 'SKY', '?': '?'}, {'to': 'Karmen', 'from': 'Jason'}]
[{'to': 'Karmen', 'from': 'SKY', '?': '?'}]
[{'to': 'RAINBOW', 'from': 'SKY', '?': '?'}, {'to': 'Karmen', 'from': 'Jason'}]
[{'to': 'RAINBOW', 'from': 'SKY', '?': '?'}, {'to': 'RAINBOW', 'from': 'SKY', '?': '?'}]
Problem 2: Don't use mutable types such as lists, dictionaries, etc. as default parameters of functions
Look at a piece of code
def f(x,l=[]):
for i in range(x):
l.append(i*i)
print(l)
print('---1---')
f(4)
print('---2---')
f(5)
Results of the:
---1---
[0, 1, 4, 9]
---2---
[0, 1, 4, 9, 0, 1, 4, 9, 16]
The expected result is:
---1---
[0, 1, 4, 9]
---2---
[0, 1, 4, 9, 16]
problem explanation
When the function is defined, the value of the default parameter list in the function is saved, that is, the id of the list is saved.
- When the list is inserted for the first time, the id of the list remains unchanged and the content changes.
- In the second call, the same id is still taken, so inserting into the same list again will continue to insert on the basis of the first call.
problem solved
def f(x,l=None):
if l is None:
l = []
for i in range(x):
l.append(i*i)
print(l)
print('---1---')
f(4)
print('---2---')
f(5)
print('---3---')
f(6)
result:
---1---
[0, 1, 4, 9]
---2---
[0, 1, 4, 9, 16]
---3---
[0, 1, 4, 9, 16, 25]