事实上, list comprehension 公认效率比 map 好 , 所以当 map 比 list comprehension 可读性好且不在乎性能时,可以优先用前者。
那问题又来了:什么时候 map 的可读性比较好? 当且只当低阶函数是您所熟悉的 Python 函数,便利的 sequence 对象也够一目了然时。 比如我就经常用它转换命令列表,够一气呵成:
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
等也能如法炮制。