如果你没有做 profiling 来证明性能有问题,那么解决方案应该是你已经提到的 listcomp:
l = [(0, x) for x in range(101)]
它可读且足够快(在大多数机器上需要 3-4 μs,这意味着您每秒可以执行超过 25 万次),所以不要费心去看除非您确实需要,否则可以提供更快的解决方案。
如果分析确实以某种方式显示这是最热门的代码,并且它实际上导致了影响性能的瓶颈,那么您可以使用微优化的废话,例如:
from itertools import repeat, count # At top of file
l = [*zip(repeat(0, 101), count())] # At point of use
它的运行时间大约是 listcomp 的 ⅔。但这充其量只是事半功倍。 如果您知道需要多次生成此精确的list,而性能确实很重要,那么解决方案是完全停止生成list。使用可读的 listcomp 制作模板,而不是按需复制该模板:
TEMPLATE_LIST = [(0, x) for x in range(101)] # At top of file (global scope)
l = [*TEMPLATE_LIST] # Slightly faster on 3.8.0, but generalized unpacking less widely known
l = TEMPLATE_LIST[:] # Slightly slower, but shallow copy idiom well-known
或者如果您想要防止对模板进行就地修改list:
MAKE_TEMPLATE_LIST = [(0, x) for x in range(101)].copy # At top of file (global scope)
l = MAKE_TEMPLATE_LIST() # At point of use
模板list 的廉价浅拷贝要快得多,而且您的所有值都是不可变的(tuples of ints),因此您不需要更昂贵的深拷贝。即使是微优化的废话解决方案(我的机器上TEMPLATE_LIST[:] 约为220-230 ns,[*TEMPLATE_LIST] 和MAKE_TEMPLATE_LIST() 都约为190-200 ns)所需的时间也不到10%,并且它的所有部分都很明显(MAKE_TEMPLATE_LIST 不太明显)。主要缺点是:
-
TEMPLATE_LIST 的定义与它的使用位置是分开的,因此维护人员必须进行交叉引用(某些 IDE 至少会提供悬停提示)
-
TEMPLATE_LIST 可修改; MAKE_TEMPLATE_LIST 更难被意外修改,但仍然可以被替换。在任何一种情况下,这都是代码纪律问题,而不是对抗的问题(“我们都是成年人”)
- 永久内存使用(与
list 这么小的无关;如果您无法承受 6 KB 的内存成本,那么 Python 可能不适合您)
TL;DR:除非您 100% 确定需要速度,否则请使用 listcomp。如果您确定,复制现有的 list 会比从头开始重建更快。