函数中的del a_list [:]和a_list = []有什么区别?

时间:2019-02-08 18:26:58

标签: python list

这只是一个问题,要求代码有所不同。

我有几个列表,即。 a=[], b=[], c=[], d=[]

假设我有一个附加到每个列表的代码,并且想将所有这些列表重置为原始的空状态,那么我创建了一个函数:

def reset_list():
  del a[:]
  del b[:]
  del c[:]
  del d[:]

因此,每当我在代码中调用reset_list()时,它都会删除所有附加项并将所有列表设置为[]。但是,以下一项无效:

def reset_list():
  a = []
  b = []
  c = [] 
  d = []

这可能是一个愚蠢的问题,但是我想知道为什么第二个不起作用。

4 个答案:

答案 0 :(得分:4)

执行del a[:]后,它将查找变量a(包括外部上下文),然后对其执行del found_a[:]

但是当您使用a = []时,它将在当前上下文中创建一个名称a并为其分配一个空列表。当该函数退出时,该函数中的变量a不再“可访问”(已销毁)。

因此,简而言之,第一个有效,因为您从外部上下文更改了a,第二个无效,因为您没有从外部上下文中修改a,而是创建了一个新的a的名称,并暂时(在功能执行期间)为其分配一个空列表。

del a[:]a = []之间有区别

请注意,如果您对原始列表有其他引用(别名),则它们实际上会有所不同。 (正如@ juanpa.arrivillaga在评论中指出的那样)

del list[:]删除列表中的所有元素,但不创建新列表,因此别名也将更新:

>>> list_1 = [1,2,3]
>>> alias_1 = list_1
>>> del alist_1[:]
>>> list_1
[]
>>> alias_1
[]

但是a = []创建一个新列表并将其分配给a

>>> list_2 = [1,2,3]
>>> alias_2 = list_2
>>> list_2 = []
>>> list_2
[]
>>> alias_2
[1, 2, 3]

如果您想更广泛地讨论Python中的名称和引用,我强烈建议您使用Ned Batchelders blog post on "Facts and myths about Python names and values"

更好的解决方案?

在大多数情况下,如果您有多个变量在一起,我会为它们使用一个类。然后,您可以简单地创建一个新实例来代替reset

class FourLists:
    def __init__(self):
        self.a = []
        self.b = []
        self.c = []
        self.d = []

然后,您可以创建一个新实例并使用该实例的属性:

>>> state = FourLists()
>>> state.a
[]
>>> state.b.append(10)
>>> state.b.extend([1,2,3])
>>> state.b
[10, 1, 2, 3]

然后,如果您想重置状态,可以简单地创建一个新实例:

>>> new_state = FourLists()
>>> new_state.b
[]

答案 1 :(得分:1)

如果您想让python使用变量的全局定义的“版本”,则需要将a,b,c,d声明为全局变量。否则,如其他答案所指出的那样,它将仅声明新的本地范围“版本”。

pg_basebackup

输出:

a = [1,2,3]
b = [1,2,3]
c = [1,2,3]
d = [1,2,3]

def reset_list():
    global a,b,c,d
    a = []
    b = []
    c = [] 
    d = []

print(a,b,c,d)
reset_list()
print(a,b,c,d)

@juanpa.arrivillaga指出,[1, 2, 3] [1, 2, 3] [1, 2, 3] [1, 2, 3] [] [] [] [] del a[:]之间存在差异。请参阅this答案。

答案 2 :(得分:1)

第一种方法之所以有效,是因为:

  • type PersonModified = { address: { line2?: string | undefined; zip: string; line1: string; }; name: string; age: number; } 仅删除四个列表的内容。只要您命名的名称相同,它就可以在您在函数外部定义的列表上使用。如果您使用其他名称,则会收到错误消息:

    reset_list()

    仅当在函数调用之前初始化列表时,该函数才会生效。这是因为在函数调用结束后您没有返回列表:

    e = [1,2,3,4]
    def reset_list():
        del a[:]   #different name for list
    
    NameError: name 'e' is not defined
    

    该函数本身不返回任何内容:

    a = [1,2,3,4] #initialize before function definition
    def reset_list():
        del a[:]
    
    reset_list() #function call to modify a
    print(a)
    #[]
    

第二种方法不起作用,因为:

  • print(reset_list()) #None 函数将创建4个空列表,这些空列表未指向该函数外部可能已定义的列表。函数内部发生的任何事情都会保留在内部(也称为 scope )并在那里结束,除非您在函数调用结束时将列表reset_list()退回。仅当调用函数时,列表才会被修改并返回。确保在函数定义的return中指定参数:

    reset_list(a,..)

如您所见,应该始终从函数中#function definition def reset_list(a): a = [] return a #initialize list after function call a = [1,2,3,4] print("Before function call:{}".format(a)) new_a = reset_list(a) print("After function call:{}".format(new_a)) #Output: Before function call:[1, 2, 3, 4] After function call:[] 来确保您的函数在列表上“完成了一些工作”并最终返回结果。

答案 3 :(得分:0)

第二个函数(带有a = [],依此类推)用本地范围(在函数内)初始化4个新列表。这与删除列表的内容不同。