【问题标题】:Why is there no list.clear() method in python?为什么python中没有list.clear()方法?
【发布时间】:2009-09-09 20:34:42
【问题描述】:

灵感来自this question.

为什么python中没有list.clear()方法?我在这里发现了几个问题,说正确的方法是以下之一,但没有人说为什么不只是一种方法。

del lst[:]
lst[:] = []

虽然它可能违背“python 的禅宗”,有不止一种做某事的方式,但对我来说,有一个“list.clear()”方法似乎更明显。它也符合 dicts 和 sets,两者都有 .clear()。

我在 python-dev 和 python-ideas 上看到了一些关于此的帖子,但没有得出明确的答案(请参阅 here (2006) 和 here (2009))。圭多有考虑过吗?这只是过去 4-5 年尚未解决的争论点吗?

更新: list.clear() 在 3.3 中被添加到 python - see here

【问题讨论】:

  • 这太荒谬了,当然知道原因是有价值的。它深入了解了语言的设计方式,并提供了对 python 的更深入理解。对于声称像 python 一样用户友好和直观的语言,我很惊讶它不存在。如果有充分的理由,我想不出一个。

标签: python list


【解决方案1】:

在您链接Raymond Hettinger pretty much sums up the pros and cons 添加该方法的线程中。在语言设计方面,保守是非常重要的。例如,参见 C# 团队拥有的 "every feature starts with -100 points" 原则。通过随意添加特性,你不会得到像 Python 那样干净的东西。看看一些更流行的脚本语言,看看它会把你带到哪里。

我猜.clear() 方法从未跨越隐含的 -100 分规则成为值得添加到核心语言的东西。尽管考虑到方法名已经用于同等目的,而且很难找到替代方法,但它可能离它并不遥远。

【讨论】:

【解决方案2】:

虽然在提出这个问题时没有 list.clear(),但 3.3 现在有一个(如 http://bugs.python.org/issue10516 中所要求的那样)。此外,clear() 方法已添加到 bytearrayMutableSequence 以方便在列表和其他集合(set、dict 等)之间切换。

可以在here找到更改的完整详细信息。

【讨论】:

    【解决方案3】:

    我无法回答为什么;但绝对应该有一个,所以不同类型的对象可以用同一个界面清除。

    一个明显、简单的例子:

    def process_and_clear_requests(reqs):
        for r in reqs:
            do_req(r)
        reqs.clear()
    

    这只要求对象支持迭代,并且它支持 clear()。如果列表有一个 clear() 方法,这可以接受一个列表或设置相等。相反,因为集合和列表有不同的 API 来删除它们的内容,所以这是行不通的;你最终会得到一个不必要的丑陋黑客,比如:

    def process_and_clear_requests(reqs):
        for r in reqs:
            do_req(r)
        if getattr(reqs, "clear"):
            reqs.clear()
        else:
            del reqs[:]
    

    就我而言,使用 del obj[:] 或 obj[:] = [] 只是令人不快、不直观的技巧来解决 list 缺少 clear() 的事实。

    这将“减少冗余”带入了一个错误,它破坏了语言的一致性,这一点更为重要。

    至于你应该使用哪个,我推荐del obj[:]。我认为对于非列表对象更容易实现。

    【讨论】:

    • 拥有一致界面的优点。我打算建议您在示例中使用 pop() (我知道这只是一个示例),但 pop() 仅用于突出界面不一致!
    • 为了简洁起见,我删除了这个注释,但是:由于类似的原因,set 的“add”和 list 的“append”也应该有相同的名称。那好吧;所有语言都有其缺陷。
    【解决方案4】:

    问题应该是为什么clear 首先被认为是必要的。以下内容用于清除我能想到的任何 Python 集合。

    def clear(x):
        return type(x)()
    
    >>> s = {1, 2, 3}
    >>> s
    set([1, 2, 3])
    >>> s = clear(s)
    >>> s
    set([])
    >>> l = [1, 2, 3]
    >>> l
    [1, 2, 3]
    >>> l = clear(l)
    >>> l
    []
    

    【讨论】:

    • 这不会清除对象——它会创建一个适当类型的新对象,它是空的。原始对象仍然是满的,它包含的任何引用仍然有效。还是我遗漏了一些明显的东西?
    • @DSM,好的,我承认这并非在所有情况下都有效,例如当对象已被传递给函数并且您试图改变原始对象时。除此之外,当原始容器被垃圾收集时,包含的任何东西都应该消失。
    • 这个方法应该更恰当地命名为“new”而不是“clear”。
    猜你喜欢
    • 1970-01-01
    • 2023-02-05
    • 1970-01-01
    • 1970-01-01
    • 2012-01-04
    • 1970-01-01
    • 1970-01-01
    • 2018-05-14
    • 2014-12-24
    相关资源
    最近更新 更多