【问题标题】:Why can't I call del [:] on a dict?为什么我不能在字典上调用 del [:] ?
【发布时间】:2011-06-09 12:30:27
【问题描述】:

这是怎么回事?

>>> a = {1: "a", 2: "b"}
>>> del a[1]
>>> a
{2: 'b'}
>>> a = {1: "a", 2: "b"}
>>> del a[:]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type
>>> a.clear()
>>> a
{}

为什么我必须打电话给dict.clear

【问题讨论】:

    标签: python dictionary datamodel


    【解决方案1】:

    a[:] 是一种快速复制list(和tuple)的方法。有关不同类型复制的说明,请参阅docs 的底部。

    因此,有理由说字典上的 del a[:] 并没有多大意义。

    如果你想删除整个字典,你可以简单地做del a

    >>> a = {1: "a", 2: "b"}
    >>> del a
    >>> a
    
    Traceback (most recent call last):
      File "<pyshell#8>", line 1, in <module>
        a
    NameError: name 'a' is not defined
    >>>
    

    【讨论】:

    • 错了。序列上的del S[:] 删除所有项目但不触及名称本身,而del S 仅删除名称而不影响项目。
    • @IgnacioVazquez-Abrams:我很困惑为什么该声明会这样。由于 s[:] 将返回列表的浅表副本,因此 del s[:] 只会删除返回的对象似乎是合乎逻辑的,但它不会那样工作。知道为什么吗?这只是语言的一些奇怪的怪癖吗?
    • @Joel:是的。 del 在名称被索引时是特殊情况,而是调用对象的 __delitem__() 方法。
    【解决方案2】:

    原因很简单:没有定义。如果有人努力捕捉空切片并委托给适当的方法,那么它没有理由无法工作。

    另一方面,这将违反分配和获取相同切片的对称原则,因此可能不会被接受。

    【讨论】:

    【解决方案3】:

    a[:] 是切片操作的一个特例,它只为序列定义。它是a[0:len(a)] 的缩写形式。 dict 不是序列。

    【讨论】:

    【解决方案4】:

    如果此功能对您的系统至关重要,您可以继承 dict 内置函数以添加此功能。

    import sys
    class newdict(dict):
    
        def __delslice__(self,i,j):
            if i==0 and j==sys.maxint:
                self.clear()
            else:
                dict.__delslice__(self,i,j)
    

    【讨论】:

      【解决方案5】:

      当您执行del a[1] 时,您并没有删除字典中的第一个元素,而是删除了键为 1 的元素。字典没有任何排序,因此没有切片算法(至少在这种情况下)。 这就是为什么使用字典a = {1 : 'one', 5 : 'five'} 你可以做del a[1] 而不能做del a[2]del a[0]

      【讨论】:

        猜你喜欢
        • 2018-01-24
        • 2020-10-06
        • 2013-01-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-13
        • 2019-03-02
        • 2017-10-14
        相关资源
        最近更新 更多