【问题标题】:defaultdict with default value 1?默认值为 1 的 defaultdict?
【发布时间】:2015-08-02 03:02:37
【问题描述】:

我是 python 新手,我从某个地方阅读了一些代码 sn-p。这是一种计数排序的实现。

代码如下:

from collections import defaultdict
def sort_colors(A):
    ht = {}                        # a hash map
    ht = defaultdict(lambda:0, ht) # with default value 1
    for i in A:
         ht[i] += 1
    ret = []
    for k in [0, 1, 2]:
        ret.extend([k]*ht[k])
    return ret

和 func 的前两行一样,它是

ht = {}
ht = defaultdict(lambda:0, ht)

我不太清楚这个初始化。你能帮我弄清楚吗?还有,我们是否应该将这两行替换为以下内容?

ht = defaultdict(int) # default value 0

【问题讨论】:

  • 只要是从集合中导入,还不如直接使用Counter
  • 这里的默认值不是1,是0。
  • 尝试ht = defaultdict(lambda: 1) # with default value 1 并删除前面的ht = {},因为您在下一行更改了ht 的值,所以没有任何效果。

标签: python defaultdict


【解决方案1】:

简答(根据下面蒙塔罗的回答)

defaultdict(lambda:1)

关于defaultdicts 工作原理的详细回答

ht = {}
ht = defaultdict(lambda:0, ht)

defaultdicts 与 dict 的不同之处在于,当您尝试使用不存在的密钥访问常规 dict 时,它会引发 KeyError
但是,defaultdict 不会不要引发错误:它会为您创建密钥。有什么价值?随着 callable 的返回,您作为参数传递。在这种情况下,每个新键都将使用值 0 创建(这是简单的 lambda 函数 lambda:0 的返回),这也恰好是 int() 的相同返回,所以在 这种情况,把默认函数改成int()没什么区别。

更详细地分解这一行:ht = defaultdict(lambda:0, ht)

第一个参数是一个函数,它是一个可调用对象。这是将被调用来为不存在的键创建新值的函数。第二个参数ht 是可选的,它指的是新的defaultdict 将在其上构建的基本字典。因此,如果ht 有一些键和值,defaultdict 也会有这些键和对应的值。如果您尝试访问这些键,您将获得旧值。 但是,如果您没有传递基本字典,则会创建一个全新的 defaultdict,因此,所有访问的新键都将获得可调用对象返回的默认值。
(在这种情况下,由于ht 最初是一个空的dict,所以在执行ht = defaultdict(lambda:0)ht = defaultdict(int)ht = defaultdict(lambda:0, ht) 时完全没有区别:它们都会构建相同的defaultdict

【讨论】:

  • (lambda:0, ht) 是否可以用 0 调用?
  • 没错。我编辑了帖子以更详细地分解它
  • 感谢您的回答。你知道如何让常数总是不同吗?我解释一下:defaultdict(lambda: 'string', ht) 将无法按预期工作,因为所有新密钥都将共享同一 'string' 实例。我怎样才能每次都提供一份副本?请注意,defaultdict(lambda: copy.copy('string'), ht) 不起作用,因为 copy 只计算一次。
  • @Dr_Zaszuś 很抱歉,但我不认为我理解你的例子。字符串是不可变的,有些是 intern 的,所以即使你使用x = "some string"b = copy.copy(x),你仍然可以找到x is b == True。所以在这种情况下使用copy 并不重要。你能再解释一下吗?
【解决方案2】:

我认为你可以只传递一个返回 1 的 lambda 函数

from collections import defaultdict

d = defaultdict(lambda: 1)

【讨论】:

    【解决方案3】:

    相当于@Montaro 的回答:

    def a():
        return 1
    
    d = defaultdict(a)
    

    【讨论】:

      猜你喜欢
      • 2015-07-06
      • 1970-01-01
      • 1970-01-01
      • 2015-10-28
      • 2021-10-10
      • 1970-01-01
      • 1970-01-01
      • 2014-05-16
      • 1970-01-01
      相关资源
      最近更新 更多