因为听起来您希望这一切都在numpy 中,所以您的问题的直接答案实际上只是一个旁白,而正确 答案直到“当然……”段落。
如果您考虑一下,您使用map 和None 第一个参数作为zip_longest,因为Python 没有zip_longest。但它确实有一个,在itertools——它允许你指定一个自定义的fillvalue。所以,您可以通过izip_longest 一步完成这一切:
>>> import itertools
>>> todayorders = [1, 2]
>>> lastyearorders = [1, 2, 3]
>>> allorders = itertools.izip_longest(todayorders, lastyearorders, fillvalue=0)
>>> list(allorders)
[(1, 1), (2, 2), (0, 3)]
这仅填充0 用于显示为较短列表的额外值的Nones;如果您想用0 替换每个 None,您必须按照Martijn Pieters 的方式进行。但我认为这就是你想要的。
另外,请注意末尾的list(allorders):izip_longest,与itertools 中的大多数内容一样,返回一个迭代器,而不是list。或者,用您可能更熟悉的术语来说,它返回一个“惰性”序列而不是“严格”序列。如果您只是要迭代结果,那实际上会更好,但是如果您需要将它与需要 list 的某些功能一起使用(例如以人类可读的形式打印出来 - 或访问 allorders[9],如在您的示例中),您需要先显式转换它。
如果您真的想要numpy.array 而不是list,您可以直接到达那里,而无需先通过list。 (如果您只想使用matplotlib 它,您可能确实想要array。)最明确的方法是使用np.fromiter(allorders) 而不是list(allorders) .您可能想传递一个明确的dtype=int(或任何合适的)。而且,如果您知道大小(您知道它是 max(len(todayorders), len(lastyearorders))),在某些情况下,传递显式 count 也会更快或更简单。
当然,如果numpy 中的任何一个听起来很吸引人,您可能首先应该留在numpy,而不是使用map 或izip_longest:
>>> todayorders.resize(lastyearorders.shape)
>>> allorders = np.vstack(todayorders, lastyearorders).transpose()
不幸的是,todayorders 发生了变异,据我所知,等效的不可变函数 numpy.resize 并没有给你任何“零扩展”的方法,而是重复这些值。希望我错了,有人会建议简单的方法,但否则,你必须明确地这样做:
>>> extrazeros = np.zeros(len(lastyearorders) - len(todayorders), dtype=int)
>>> allorders = np.vstack(np.concatenate((todayorders, extrazeros)), lastyearorders)
>>> allorders = allorders.transpose()
array([[ 1, 1],
[ 2, 2],
[ 0, 3]])
当然,如果你做了很多这样的事情,我会编写一个 zeroextend 函数,它接受一对数组并扩展一个以匹配另一个(或者,如果你不只是处理一维,扩展在每个轴上缩短一个以制作另一个)。
无论如何,除了比使用map、izip_longest 等更快和使用更少的临时内存之外,这也意味着你最终得到了一个正确的数组 dtype (int而不是object)——这意味着你的结果也会使用更少的长期记忆,从那时起你所做的一切也会更快并且使用更少的临时记忆。
为了完整性:可以让 pyplot 处理 None 值,但我认为这不是您想要的。例如,您可以传递一个Transform 对象,其transform 方法将None 转换为0。但这实际上与 Martijn Pieters 的答案相同,但更加冗长,除非您需要绘制大量此类数组,否则根本没有任何优势。