【问题标题】:How to empty a list?如何清空列表?
【发布时间】:2009-09-09 16:08:21
【问题描述】:

以这种方式清空列表似乎很“脏”:

while len(alist) > 0 : alist.pop()

是否有明确的方法可以做到这一点?

【问题讨论】:

  • 那么为什么python dicts 和sets 有clear() 方法,而没有lists?
  • 但是如果有多个对象的引用,它可能会有用。
  • 如果我需要在运行时清除进程的共享列表并且不需要等待垃圾处理(或者我错了吗?我误解了垃圾收集吗?),这可能会很有用。另外,如果我想检查每个弹出的元素,我可以在无法使用切片的情况下对其进行调试(或者我错了)。我不需要在清除列表时停止进程执行。
  • @S.Lott 仅仅因为你不明白为什么这很重要并不意味着我们其他人不明白。如果多个对象依赖于一个公共列表,这将很重要。在几种设计模式中,这很重要。垃圾收集器意味着您不必自己清理;这不是制造更多混乱的许可。
  • 尽管有任何其他更好的答案,但您的初始代码可能已经编写:while alist: alist.pop()

标签: python list


【解决方案1】:

这实际上是从列表中删除内容,但不会用新的空列表替换旧标签:

del lst[:]

这是一个例子:

lst1 = [1, 2, 3]
lst2 = lst1
del lst1[:]
print(lst2)

为了完整起见,切片赋值的效果是一样的:

lst[:] = []

它也可以用来缩小列表的一部分,同时替换一部分(但这超出了问题的范围)。

注意lst = []不会清空列表,只是创建一个新对象并将其绑定到变量lst,但旧列表仍然会有相同的元素,如果它有其他的效果会很明显变量绑定。

【讨论】:

  • 另外两个问题:“del”到底是什么? (我推断它删除了一些东西,但我真的不知道它是什么)和第二个:你怎么读(大声)[:]
  • 对于 del 的合理解释,我会参考文档:docs.python.org/reference/simple_stmts.html#the-del-statement
  • 我通常不会大声读出 python 代码 xD,但如果我不得不说,我想我会说“从列表 l 的开头到结尾切片”。
  • @jellybean 完全无意^_^ 英语不是我的母语,所以我真的没有注意到两个cmets之间的对比。
  • 如果我们这样做 l = [] 旧的列表内容不会被 Python GC 收集起来吗?
【解决方案2】:

如果您运行的是 Python 3.3 或更高版本,则可以使用 listclear() 方法,该方法与 dictsetdeque 和其他可变容器类型的 clear() 并行:

alist.clear()  # removes all items from alist (equivalent to del alist[:])

根据链接的文档页面,同样可以使用alist *= 0 来实现。

综上所述,有四种等效的方法可以就地清除列表(与Zen of Python! 完全相反):

  1. alist.clear() # Python 3.3+
  2. del alist[:]
  3. alist[:] = []
  4. alist *= 0

【讨论】:

  • 这个答案应该在最上面,stackoverflow有什么问题!
【解决方案3】:

你可以试试:

alist[:] = []

这意味着:在[:]位置处拼接列表[](0个元素)(从头到尾的所有索引)

[:] 是切片运算符。请参阅this question 了解更多信息。

【讨论】:

  • 为什么不只是alist = []
  • @mitenka 不会清空列表,它会用另一个恰好为空的列表覆盖变量 alist。如果其他人有对原始列表的引用,则保持原样(即它包含开头的任何内容)
  • @mitenka 另一个原因是alist.clear()alist[:] = [] 有助于检查alist 是否真的是一个列表。假设您从函数foo() 返回了alist。你以为foo 返回了一个列表,但实际上它返回了一个None。使用alist = [] 无法发现该错误。
  • 我看到这篇文章是因为我正在寻找一种清除列表的方法,或者至少我认为这是我需要做的。我正在接收数据并想根据条件创建子列表并将子列表放入主列表中。自然,当我使用任何删除方法时,它会删除子列表和我添加到主列表中的列表。 Mitenka 的建议正是我所需要的。想一想,我不需要清除子列表,我需要将其重置回一个新列表。对我来说,这并不明显是我需要的。 Mitenka 的建议解决了我的问题。
【解决方案4】:

事实证明,使用 python 2.5.2,del l[:]l[:] = [] 慢 1.1 微秒。

$ python -mtimeit "l=list(range(1000))" "b=l[:];del b[:]"
10000 loops, best of 3: 29.8 usec per loop
$ python -mtimeit "l=list(range(1000))" "b=l[:];b[:] = []"
10000 loops, best of 3: 28.7 usec per loop
$ python -V
Python 2.5.2

【讨论】:

  • 在 Python 2.7.2 中,在我的机器上,它们大致相同。它们每个循环的运行时间都是 13.5-13.7 微秒。
  • 你还应该测量 python3 -mtimeit "l=list(range(1000))" "b=l[:]" 来计算 "b[:] = []" 和 "del b[ :]”。做吧,哈哈……
  • 我用 python 3.5 做了基准测试,我同意 leetNightshade 。 .clear()del b[:]b[:]=[] 都运行相同(b[:]=[] 稍慢。
【解决方案5】:
lst *= 0

效果和

一样
lst[:] = []

它更简单一些,也许更容易记住。除此之外没什么好说的

效率好像差不多

【讨论】:

  • 为了完整起见,值得一提的是,任何小于或等于0 的给定整数都将具有相同的效果。虽然这是一个非常巧妙的技巧,但我有点难过,它没有受到太多关注..
【解决方案6】:
list = []

list 重置为空列表。

请注意,您通常不应隐藏保留的函数名称,例如 list,它是列表对象的构造函数 - 例如,您可以使用 lstlist_

【讨论】:

  • 否:这不会修改列表,这只是将一个空列表分配给变量list。如果您希望一个函数修改传入的列表(例如),这不会做您想要的。
  • 并非如此。问题是“如何清空列表”而不是“如何分配包含列表的变量”
  • 问题并没有歧义,操作的 sn-p 正在从列表中弹出元素(就是这样,就地修改它)...
  • 另外,“list”不应该用作变量名,因为它会遮蔽“list”类型。许多 Python 开发人员使用“L”作为列表变量名,但我更喜欢“lst”。
  • 有时您只想清空列表,这与建议的任何方法一样好。可能更快
【解决方案7】:

您可以使用的另一个简单代码(取决于您的情况)是:

index=len(list)-1

while index>=0:
    del list[index]
    index-=1

你必须从列表的长度开始索引,然后从 0 开始向后移动,然后从 0 开始向前移动,因为这会导致索引与列表的长度相等,并且只会被减半。

此外,请确保 while 行带有“大于或等于”符号。省略它会留下 list[0] 剩余。

【讨论】:

  • 用立方体重新发明轮子
  • 哈哈。这是我在 SO 上遇到的第二个奇怪的答案(+ 适当的评论)。这些令人难忘的东西应该有一个网站:D
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-05-17
  • 2017-09-08
  • 1970-01-01
  • 1970-01-01
  • 2012-12-21
  • 1970-01-01
  • 2012-05-09
相关资源
最近更新 更多