【问题标题】:completely delete a list in python完全删除python中的列表
【发布时间】:2016-08-23 15:12:56
【问题描述】:

我正在使用 python 2,并尝试删除两个列表。 代码如下:

test_data1 = [img for img in glob.glob("/location/of/images/*png")]
test_data0 = [img for img in glob.glob("/location/of/other_images/*png")]
test_data = test_data1 + test_data0

每个图像列表都包含数百万个文件名,因此我希望在创建 test_data 列表后删除不必要的列表。只是为了让代码“更容易”让计算机运行。

我该怎么做?

我发现了几种不同的方法,但没有任何一种方法涉及内存问题。我不确定test_data1=[] 是否真的从内存中完全删除了列表。

另外我担心test_data = test_data1 + test_data0这一行只结合了列表的哈希值,当我删除这两个列表时,test_data 也会变成空的。

那么..正确的方法是什么?

非常感谢您的帮助! 对不起,如果英语不好,我不是母语:P

谢谢!

【问题讨论】:

  • 删除一些东西只需使用del关键字
  • 喜欢del test_data0。此外,如果您删除 2 个原始列表(例如 tset_data0test_data1),最后一个(test_data)将保持不变,因为它是一个新列表

标签: python list python-2.7 memory


【解决方案1】:

您可以使用列表连接来消除对中间列表的需要

test_data = []
test_data += [img for img in glob.glob("/location/of/images/*png")]
test_data += [img for img in glob.glob("/location/of/other_images/*png")]

此外,我不确定您的程序的整体设计是什么,但出于这个原因,Python 中倾向于使用迭代器/生成器而不是列表。你必须一次记住的越少越好。看看你是否可以重新设计你的程序,让它在运行中进行迭代,而不是建立这个庞大的列表。

【讨论】:

  • 特别是,itertools.chain 在这个特定示例中可能会被证明是有用的。
  • 您说“不再需要中间列表”,但您仍在这样做,即创建中间列表。
  • 这不像[img for img in glob.glob("/location/of/images/*png")] 不是一个列表。就内存使用而言,它与原始代码完全没有区别
【解决方案2】:

您可以使用extend()。这将实例化一个列表并用这些项目填充它,并且extend 将该列表附加到test_data。这样,内存中列表存在的唯一位置将是test_data。与多个实例相反。这是否会对性能产生任何实际影响只能通过测试/分析来确定。

test_data = []
test_data.extend([img for img in glob.glob("/location/of/images/*png")])
test_data.extend([img for img in glob.glob("/location/of/other_images/*png")])

或使用del,清除该变量的绑定(垃圾收集器将删除未使用的值)。

l = [1,2,3,4,5]
del l  # l cleared from memory. 

【讨论】:

    【解决方案3】:

    像其他答案一样向数组添加新数据的选项有效,但如果您想继续拥有两个数组并添加它们,请考虑使用垃圾收集器。

    Python 有一个垃圾收集器,它会在对象不再使用时将其删除(即当对象无法访问且不再被引用时)。例如,如果您有程序:

    a = [1, 2, 3, 4]
    a = []
    #  Here data [1, 2, 3, 4] is unreachable (unreferenced)
    ....
    

    垃圾收集器最终可能会删除对象 [1, 2, 3, 4]。你不能保证什么时候。它会自动发生,您无需对其进行任何操作。

    但是,如果您担心内存资源,可以使用gs.collect() 强制垃圾收集器删除未引用的对象(不要忘记import gc)。例如:

    import gc
    
    a = [1, 2, 3, 4]
    a = []
    gc.collect()
    #  Here it is guaranteed that the memory previously occupied by [1, 2, 3, 4] is free
    

    所以你的程序会变成

    import gc
    
    test_data1 = [img for img in glob.glob("/location/of/images/*png")]
    test_data0 = [img for img in glob.glob("/location/of/other_images/*png")]
    test_data = test_data1 + test_data0
    
    test_data1 = []
    test_data0 = []
    
    gc.collect()
    

    【讨论】:

      【解决方案4】:

      事实上,每个列表都存储对字符串的引用,而不是字符串本身。

      我很确定,使用的内存大约是 1M x 4(对于 32 位架构)或 1M x 8(对于 64 位架构)。

      我建议你做分析,见Which Python memory profiler is recommended?

      您可以使用glob.iglob 来使用迭代器而不是列表,并将列表与itertools.chain 链接起来,如下所示:

      import itertools
      import glob
      
      iter1 = glob.iglob("/location/of/images/*png")
      iter2 = glob.iglob("/location/of/other_images/*png")
      
      test_data = [name for name in itertools.chain(iter1, iter2)]
      

      【讨论】:

        猜你喜欢
        • 2021-01-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-03-10
        • 1970-01-01
        • 2017-08-20
        • 1970-01-01
        • 2017-07-20
        相关资源
        最近更新 更多