【Python】收集python编程中碰到的坑

本文列举了Python编程中常见的29个陷阱,包括遍历删除列表元素、引用赋值、input处理、for循环变量修改、remove与del的区别、字典items()类型、元组与列表转化、迭代器与列表内容修改等。还涉及numpy、matplotlib、networkx库的使用误区,以及函数默认参数、lambda表达式、全局变量和多进程中的陷阱。理解这些陷阱有助于避免编程错误,提高代码质量。
摘要由CSDN通过智能技术生成

 

【最新更新】

  • 千万别用numpy数组代替矩阵操作

numpy中的数组相乘,是对应元素相乘;

矩阵相乘时,行列相乘后加起来,才是当前元素值;

如果A*B中的任意一项为对角数组或对角矩阵,则A*B结果相同;

1-A时,如果A是数组,则这里的1表示[[1,1,1,1,1], ..., [1,1,1,1,1]](不是单位矩阵);

             如果A是矩阵,则这里的1表示对角矩阵(单位矩阵);

数组乘法默认的是点乘,矩阵默认的是矩阵乘法,混合在一起默认的是矩阵乘法;

multiply转化为对应元素的乘积,dot(d,f)会转化为矩阵的乘积;

import numpy as np

a = np.diag([1,2,3])
b = np.diag([4,5,6])
c = np.mat([[0.1,0.2,0.3],[0.4,0.5,0.6],[0.7,0.8,0.9]])

print("区分 h_stack 和 column_stack")
print(np.hstack((a, b)))
print(np.column_stack((a, b)))

print("# 区分 数组乘法 和 矩阵乘法")
print(a*c)
print(a.dot(c))

print("区分 全1矩阵(数组) 和 单位矩阵(数组)")
print(1-a)
print(np.diag([1,1,1])-a)

print("全1数组*对角数组 = 单位数组*对角数组")
print((1-a)*b)
print((np.diag([1,1,1])-a)*b)
  • 嵌套字典,不能用for循环初始化

我定义了一个嵌套字典,像一开始就初始化所有值:

dates = ['20200120', '20200121', '20200122']
dates_dic = dict(zip(dates, [{"colomn0": 0,"colomn1": 0, "colomn2": 0} for j in range(len(dates))]))

# 打印结果
print(dates_dic['20200120'])
print(dates_dic['20200120'])
dates_dic['20200120'] = 999
print(dates_dic['20200120'])
print(dates_dic['20200120'])

结果如下:

{'colomn0': 0, 'colomn1': 0, 'colomn2': 0}
{'colomn0': 0, 'colomn1': 0, 'colomn2': 0}
999
999

可见,一个被赋值,所有跟着改变。

 

 

  • Linux环境下的路径一定要使用斜杠“/”而不要使用反斜杠“\”。否则识别不出来。

>>> os.path.exists(r"csv2\appl")
False
>>> os.path.exists(r"csv2\\appl")
False
>>> os.path.exists(r"csv2/appl")
True
  • 千万不要一边遍历文件夹,一边使用shutil.move。会移动错误的文件。

  • 给变量初始化时,赋值为可变对象


任何变量的初始化赋值,要么为空(None)、要么为不可变对象(数字、元祖、字符串)。千万不要初始化为可变对象(列表,字典)。

具体原因见《改变字典中一个key的value值,另一个不相关的key-value值也被改变了》:https://blog.csdn.net/ztf312/article/details/89577328

坑1:一边遍历,一边删除列表元素

可能出现问题:下标超出范围报错,或者返回结果不正确。

python 的列表遍历删除

a=[1,2,3,4,5,6,7]
b=[1,3,6]
for it in a:
    if it not in b:
        print("remove ", it)
        print(a)
        a.remove(it)
        print(a)
remove  2
[1, 2, 3, 4, 5, 6, 7]
[1, 3, 4, 5, 6, 7]
remove  4
[1, 3, 4, 5, 6, 7]
[1, 3, 5, 6, 7]
remove  7
[1, 3, 5, 6, 7]
[1, 3, 5, 6]

如果是字典一边遍历一边删除报错,像下面这样:

# result 是一个字典, 我想把里面属性值是None的属性删除
for key in result:
	if not result[key]:
		result.pop(key)
		continue

-----------------------------------------------------

RuntimeError: dictionary changed size during iteration   # 字典在迭代的时候改变了字典大小

一个失败的尝试是,定义keys=dic.keys(),将keys独立出dic。由于函数返回值是其内部值的索引,keys仍然会随dic变换。 
成功的尝试是,使用keys=list(dic.keys())另存一个变量,重新申请内存空间。这时遍历删除成功!

keys = list(result.keys())
for key in keys:
	if not result[key]:
		result.pop(key)
		continue

坑2:b=a,修改a,结果b也被改变了。

python的内存管理机制

坑3:input输入一个数字,使用时发现变成了字符串。

如果想使用input()函数输入一个数值,在得到结果后需要用int()将字符串类型转换为数值类型。

坑4:在for循环体内改变循环变量的值,结果下次循环依然不被影响。

for i in range(3):
	print "original:",i
	i=i+3
	
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值