更新汇总一些关于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),基本形式是
1
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。
故可以这样遍历目录所有文件:1
2
3for root, dirs, files in os.walk("."):
for f in files:
print os.path.join(root, f)注意list()生成的新对象并不是完全的深拷贝,考虑如下代码:
代码来自deep copy list1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
231, 2, 3], [4, 5, 6]] a = [[
b = list(a)
a
[[1, 2, 3], [4, 5, 6]]
b
[[1, 2, 3], [4, 5, 6]]
0][1] = 10 a[
a
[[1, 10, 3], [4, 5, 6]]
# b changes too -> Not a deepcopy. b
[[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]]
0][1] = 9 a[
a
[[1, 9, 3], [4, 5, 6]]
# b doesn't change -> Deep Copy b
[[1, 10, 3], [4, 5, 6]]
事实上list()确实生成了新对象(可以用id查看),但是对于里面的嵌套list对象仅仅是浅拷贝,如果是数字这样的不可变对象则是完全的复制,如 a = [1,2,3,4] b = list(a)