列出理解和类型的副本

时间:2018-06-26 19:42:52

标签: python memory list-comprehension

在使用列表推导时,我经常很想 not 来创建新列表,因为如果列表很大,则意味着需要更多的计算空间(据我了解,列表不是bieng在自己的情况下使用了别名,将为新列表创建一个新的内存空间)

作为一个说明性示例(可以一行完成):

def average_list(lst):
    lst = [x for x in lst if x > 0]
    return np.average(lst)

以这种方式在作业的左右部分使用lst是否危险?如果是这样,重用lst会在什么情况下引起问题?

如果是这样,为什么这个“更安全”呢?

def average_list(lst):
    clean_lst = [x for x in lst if x > 0]
    return np.average(clean_lst )

3 个答案:

答案 0 :(得分:3)

def average_list(lst):
    lst = [x for x in lst if x > 0]
    return np.average(lst)

caller_list = [1,4,-5]
average_list(caller_list)
# caller_list is unchanged

在这里,您仅在函数中重用lst名称,但没有在调用方上下文中更改lst(并且垃圾回收无法正常工作,因为调用方仍持有引用在数据上)

因此重新分配变量名是绝对安全的,但有时被认为是不好的做法,因为不应更改所传递参数的值或引用。

注意:对于list,一种更改数据本身的方式(会使函数用户感到惊讶,所以不要这样做)将是(仅适用于列表,更普遍地是 mutable < / em>对象)

    lst[:] = [x for x in lst if x > 0]

使用此切片分配,名称不会被重用,对象本身会被重用和修改。列表的原始内容将由新内容替换,由于新的过滤版本中的数据较少,因此该列表将缩小。在局部和全局变量上很酷,但是应该避免在作为参数传递的列表中使用(例如,appendpop在一般情况下也应避免使用,始终遵循最小惊讶原则)

答案 1 :(得分:1)

只要需要更长的时间来使用lst,就没有危险,而且重复使用确实可以节省内存,因为原始的lst将丢失其引用并被垃圾回收回收。 / p>

答案 2 :(得分:0)

只要您不需要原始列表值,就可以重用原始列表。