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
添加回答
舉報