事实上,list comprehension 公认效率比 map 好所以当 map 比 list comprehension 可读性好且不在乎性能时,可以优先用前者。

那问题又来了:什么时候 map 的可读性比较好?当且只当低阶函数是你所熟悉的 Python 函数,便利的 sequence 对象也够一目了然时。比如我就经常用它转换命令列表,够一气呵成:

1
2
3
4
5
6
7
8
traincascade_command = [
command_pathname,
'-w', weight,
'-h', height,
'vec', vec_pathname,
]
traincascade_command = map(str, traincascade_command)
subprocess.call(traincascade_command)

妈妈再也不用担心我不小心传 int, pathlib.Path 进命令列表了,写的 list comprehension 又长又臭得超出 79 个字符了。同理,rects = map(int, rect_strs), positives = map(abs, integers) 之类的精炼表达式也可以。

因为你很清楚 str, int 和 abs 等是一元函数,作用是什么;反之,即用你所不熟悉的 Python 函数,比如 a = map(b, c), 这时你往往会产生四重疑惑:

其一,b 是一个 callable 对象吗?
其二,b 可以只接受一个形参吗,即它到底是不是一元函数?
其三,c 是否为 sequence 对象?
其四,c 的 iterable 元素又是什么鬼?

更别说用雪上加霜的 lambda 了。

但换用 list comprehension 就没这问题:a = [b(d) for d in c], 显然 b(d) 表达了 b 彻彻底底是个一元函数,且 c 作为 sequence 对象时 iterable 元素是 d, 最终 a 会被 bind 到一个 list 对象。可读性更胜一筹。

举一反三,你可以琢磨什么情况下 filter, funtools.reduce 等也能如法炮制。

Comentários