我有這樣的代碼:
from sys import getsizeof as sizer
test_list = [i for i in range(10)]
test_list2 = list([i for i in range(10)])
test_list3 = []
for i in range(10):
test_list3.append(i)
print(f"""{sizer(test_list)} bytes: {test_list}
{sizer(test_list2)} bytes: {test_list2}
{sizer(test_list3)} bytes: {test_list3}""")
下一個結果:
184 bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
136 bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
184 bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
問題是:為什么使用創建的串列list([])重量小于使用創建的串列[]or for _ in condition?
uj5u.com熱心網友回復:
Python 中的串列沒有固定大小。隨著專案的添加和洗掉,它們會擴展和收縮。為了實作這一點,有時需要將串列移動到記憶體中的不同位置。由于復制每個添加/洗掉的元素會大大減慢操作速度,因此 Python 可以在決定進行移動時為串列分配一些空閑空間。根據您定義串列的方式,串列的大小可能正是需要的大小,或者包含一些空位元組以填充新元素。
如果我們添加更多元素,我們可以看到差異被否定:
for i in range(1):
test_list.append(i)
test_list2.append(i)
test_list3.append(i)
print(f"""{sizer(test_list)} bytes: {test_list}
{sizer(test_list2)} bytes: {test_list2}
{sizer(test_list3)} bytes: {test_list3}""")
184 bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
184 bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
184 bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
uj5u.com熱心網友回復:
(此答案中的詳細資訊取決于實作,它們是為匹配 CPython 3.10.0 而撰寫的。Python 的其他版本或其他實作的作業方式不同。)
Python 中的串列是動態大小的,不幸的是,我們的計算機生活在硬體領域,記憶體是物理的,無法壓縮或拉伸。
因此,如果您將串列加長,通過在其上附加一些內容,Python 將不得不分配新的記憶體位并將所有舊單元格復制到新記憶體中。
現在這在大多數情況下都非常快,但所有這些都加起來了。如果您想一次將 1000 個元素添加到一個空串列中,這意味著您總共必須復制大約一百萬個單元格。
因此,為了確保不必經常這樣做,Python 通常會過度分配所需的空間。例如,如果您將單個專案添加到空串列中,它將分配多個單元格,因此 Python 不必為接下來添加的幾個專案分配更多單元格。無論您使用list.append添加專案還是使用串列推導,這都是正確的。
現在還有其他方法可以創建串列。值得注意的是,您可以使用以下語法從現有的可迭代物件創建串列:list(obj). 它適用于任何可迭代物件,但如果len(obj)有效,Python 只需分配一次記憶體,使用它需要的確切單元數。所以這就是區別。您也可以將其寫為list(range(10)),在這種情況下,您不需要創建中間串列,它會過度分配。
作為獎勵,試試這個:
lists = [[], [1], [1, 2], [1, 2, 3]]
for lst in lists:
print(sizer(lst), lst)
這里的模式是什么?你知道為什么圖案是這樣的嗎?
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/518387.html
