在使用列表推导时,我经常很想 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 )
答案 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]
使用此切片分配,名称不会被重用,对象本身会被重用和修改。列表的原始内容将由新内容替换,由于新的过滤版本中的数据较少,因此该列表将缩小。在局部和全局变量上很酷,但是应该避免在作为参数传递的列表中使用(例如,append
,pop
在一般情况下也应避免使用,始终遵循最小惊讶原则)>
答案 1 :(得分:1)
只要需要更长的时间来使用lst
,就没有危险,而且重复使用确实可以节省内存,因为原始的lst
将丢失其引用并被垃圾回收回收。 / p>
答案 2 :(得分:0)
只要您不需要原始列表值,就可以重用原始列表。