2 回答
TA贡献1891条经验 获得超3个赞
如果你想要一个更快的解决方案,你可以使用itertools.repeat:
from itertools import repeat:
list(zip(repeat(0), range(101)))
基准:
%timeit [(0, x) for x in range(101)]
# 3.64 µs ± 19.1 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
%timeit list(zip(repeat(0), range(101)))
# 2.81 µs ± 35.3 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
另一个Pythonic解决方案:
list((0, x) for x in range(101))
TA贡献1828条经验 获得超6个赞
如果您尚未进行性能分析以证明性能是一个问题,那么解决方案应该是您已经提到的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 的 2/3。但这充其量只是一个折衷措施。如果您知道需要多次生成此精确列表,并且性能确实很重要,那么解决方案就是完全停止生成列表。使用可读的列表复合来制作模板,而不是按需复制该模板:
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
模板的廉价浅层副本要快得多,而且很方便,您的所有值都是不可变的(s of s),因此您不需要更昂贵的深度副本。这运行时间不到微观优化的无意义解决方案所需时间的10%(在我的机器上约为220-230 ns,两者和大约190-200 ns),并且它的所有部分都是显而易见的(不太明显)。主要缺点是:listtupleintTEMPLATE_LIST[:][*TEMPLATE_LIST]MAKE_TEMPLATE_LIST()MAKE_TEMPLATE_LIST
的定义与使用位置分开,因此维护者必须交叉引用(一些IDE至少可以帮助悬停提示)TEMPLATE_LIST
TEMPLATE_LIST可修改; 很难意外修改,但仍然可以更换。无论哪种情况,这都是代码纪律的问题,而不是要争斗的事情(“我们都是成年人在这里”)MAKE_TEMPLATE_LIST
永久内存使用(与这么小无关;如果你很难为6 KB的内存付出代价,也许Python对你来说是错误的语言)list
TL;DR:使用 listcomp,除非你 100% 确定你需要这个速度。如果您确定,复制现有内容将比从头开始重建它更快。list
添加回答
举报