更新汇总一些关于python的小技巧
if A is not None 效率要比 if A 要一些,如果 A 是 list,那么 if A 等同于 if len(A) 及 if A is not None。更多解释见if-a-vs-if-a-is-not-none
如果你需要使用类似 if classname 之类的条件判断可以在类中定义__nonzero__方法(3.x用__bool__)来返回True或False,如果这个方法在类中没有定义,len()会被调用,只要不是零就会返回True,如果两个都没有定义那么类的实例if instance 都是True。
递归遍历目录时经常会用到os.walk(还有os.path.walk,但推荐前者,因为兼容python3),基本形式是
for root, dirs, files in os.walk(".")
那么每一个循环的结果是什么呢?
假设目录是:
.
..
a-dir/
b-dir/
t.txt
那么输出就是:
第一个循环:
root .
dirs [a-dir, b-dir]
files [t.txt]
第二个循环:
root ./a-dir
dirs []
files []
结合官网文档可以知道,每一个循环是由str类型的root路径,root路径下的文件夹dirs和files组成,并且dirs和files都是只在当前root下的;接着的循环会进入第一个文件夹,同样root被替换成./a-dir,之后都是一样的list类型的dirs和files。
故可以这样遍历目录所有文件:for root, dirs, files in os.walk("."): for f in files: print os.path.join(root, f)
注意list()生成的新对象并不是完全的深拷贝,考虑如下代码:
代码来自deep copy list>>> a = [[1, 2, 3], [4, 5, 6]] >>> b = list(a) >>> a [[1, 2, 3], [4, 5, 6]] >>> b [[1, 2, 3], [4, 5, 6]] >>> a[0][1] = 10 >>> a [[1, 10, 3], [4, 5, 6]] >>> b # b changes too -> Not a deepcopy. [[1, 10, 3], [4, 5, 6]] Now see the deepcopy operation >>> b = copy.deepcopy(a) >>> a [[1, 10, 3], [4, 5, 6]] >>> b [[1, 10, 3], [4, 5, 6]] >>> a[0][1] = 9 >>> a [[1, 9, 3], [4, 5, 6]] >>> b # b doesn't change -> Deep Copy [[1, 10, 3], [4, 5, 6]]
事实上list()确实生成了新对象(可以用id查看),但是对于里面的嵌套list对象仅仅是浅拷贝,如果是数字这样的不可变对象则是完全的复制,如 a = [1,2,3,4] b = list(a)