1、使用默认可变参数的使用需要注意的地方:
def append(n, l=[]):
l.append(n)
return l
print(append(0)) # [0]
print(append(1)) # [0, 1]
是不是觉得很奇怪,跟想象的结果不一样,那是因为函数参数默认值是在函数定义的时候定义的,而不是函数执行的时候定义的。说白了,当第一次执行append(0)时,函数参数l=[],而当第二次执行append(1)的时候,函数参数l=[0]。所以你需要将上面的代码修改如下:
def append(n, l=None):
if l is None:
l = []
l.append(n)
return l
print(append(0)) # [0]
print(append(1)) # [1]
2、可以使用推导式使代码更短更清晰:
squares = {}
for i in range(10):
squares[i] = i * i
print(squares)
可以使用推导式替换代码:
squares = {i: i * i for i in range(10)}
print(squares)
上面是对字典的操作,其他的如list,gen,set也都可以这样操作。
3、但是有时候不是所有的推导式的代码都是易读的:
# 长度为 n * n 的 x, y的矩阵乘积
def function(x, y, n):
return [
sum(x[n * i + k] * y[n * k + j] for k in range(n))
for i in range(n)
for j in range(n)
]
上面的函数是求长度为 n * n 的 x, y的矩阵乘积,一眼望过去还是很难理解的。但是如果将实现内容修改一下,代码就会容易理解一些:
def function(x, y, n):
r = []
for i in range(n):
for j in range(n):
ij = sum(x[n * i + k] * y[n * k + j] for k in range(n))
r.append(ij)
return r
4、需要特别注意对type()进行==操作,有可能结果不是你期望的:
from collections import namedtuple
def checking_type():
Ponit = namedtuple('Ponit', ['x', 'y'])
p = Ponit(1, 2)
if type(p) == tuple:
print("it is a tuple")
else:
print("it is not a tuple")
你以为上面的结果应该是等于命名元组类型,但实际运行结果为it is not a tuple。你应该用inistance去做判断
from collections import namedtuple
def checking_type():
Ponit = namedtuple('Ponit', ['x', 'y'])
p = Ponit(1, 2)
if isinstance(p, tuple):
print("it is a tuple")
else:
print("it is not a tuple")
isinstance() 与 type() 区别:
type() 不会认为子类是一种父类类型,不考虑继承关系。
isinstance() 会认为子类是一种父类类型,考虑继承关系。
如果要判断两个类型是否相同推荐使用 isinstance()。
5、对于None, True, False的比较用法
def function(x):
if x == None:
pass
if x == True:
pass
if x == False:
pass
需要改成
def function(x):
if x is None:
pass
if x is True:
pass
if x is False:
pass
我们可以扩展一下,其实对于a == b做的是值的比较,而对于a is b做的是地址的比较。