我有一个非常大的Python 2D列表L,它是对称的,即L[x][y]==L[y][x]
。它保存整数元组。我创建它的方式是首先设置 L[x][y]
的值对于所有可能的 x 和 y,使得 x<=y。然后我设置L[x][y]=L[y][x]
对于所有 x 和 y,使得 x>y,这样我就不必一直检查对于一对 [x][y] 是否有 x>=y 或 xL[x][y]。
此列表的大小有何影响?我的逻辑是因为 L[x][y]
因为 x>y 保存的是引用而不是元组,那么它不应该占用 RAM 中那么多的空间。是这样吗?如果我只是设置 L[x][y]
仅限x<=y
,我可以获得大约一半大小的列表吗?
最佳答案
简短的回答 - 是的。但为了证明这一点,我们举两个例子并使用 memory_profiler .
版本 1,无引用
def build_symmetric_list(n) :
l = []
for x in range(0,n) :
ll = []
for y in range(0,n) :
if x<= y:
ll.append((x,y))
else :
ll.append((y,x))
l.append(ll)
return l
@profile
def test_a():
a = build_symmetric_list(1000)
test_a()
-
Line # Mem usage Increment Line Contents
13 9.848 MiB 0.000 MiB @profile
14 def test_a():
15 106.941 MiB 97.094 MiB a = build_symmetric_list(1000)
版本 2,带引用
def build_symmetric_list_with_references(n) :
l = []
for x in range(0,n) :
ll = []
for y in range(0,n) :
if x<= y :
ll.append((x,y))
else :
ll.append(l[y][x]) #by reference
l.append(ll)
return l
@profile
def test_b() :
b = build_symmetric_list_with_references(1000)
test_b()
和结果:
Line # Mem usage Increment Line Contents
================================================
13 9.848 MiB 0.000 MiB @profile
14 def test_b() :
15 65.047 MiB 55.199 MiB b = build_symmetric_list_with_references(1000)
所以 97 mb vs 55 - 大约一半。请记住,由于元组是不可变的,因此对 L[x][y] 的重新分配不会反射(reflect)在 L[y][x] 中(可能会使列表的对称性失效)。
关于python - python 中的大型对称列表 : will references contribute to size in ram?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25735950/