Ruby中与Python的defaultdict相对应的是什么?

26

在Python中,我可以创建一个哈希表,在第一次引用每个元素时都具有默认值(也称为“自动创建”)。这是一个示例:

from collections import defaultdict
d = defaultdict(int)
d["new_key"] += 1
print d

打印该字典,可以看到“new_key”的值为1。

在Ruby中,相应的代码是什么?执行此代码会出现错误:

d = {}
d[:new_key] += 1
puts d

test.rb:3:in `<main>': undefined method `+' for nil:NilClass (NoMethodError)
3个回答

28

您可以使用 default= 来分配默认值:

d.default = 0
请注意,这并不会真正地自动生成,它只是使得d[:new_key]返回零值而不会实际添加:new_key键。如果你想修改默认值,default=也可能会导致问题;这意味着d.default = [ ]几乎总是错误的,因为在访问默认值时数组不会被复制。
通常更好的选择是使用default_proc=
d.default_proc = proc { |h, k| h[k] = 0 }

这使您可以拥有不同的默认值,并允许您添加新键(或不添加,这取决于proc的结构如何)。

在创建Hash时,您也可以设置它们:

d = Hash.new(0)
d = Hash.new { |h, k| h[k] = 0 }

1
我同意。我无法删除我的答案,所以我会在上面添加一条注释。 - tessi

19

你可以使用 Hash.new 方法的第一个参数来实现:

d = Hash.new 0
d[:new_key] += 1
d[:new_key] #=> 1
d[:foo]     #=> 0

小心 - 你可能会意外更改默认值:

h = Hash.new("Go Fish")
h[:unknown_key]         #=> "Go Fish"
h[:unknown_key].upcase! #=> "GO FISH"
h[:next_key]            #=> "GO FISH"

正如“mu is too short”在他的答案中指出的那样,你最好使用proc,例如:

h = Hash.new { |h, k| h[k] = 0 }

你如何创建一个带有默认值和键 :unknown_key:next_key 的哈希表? - user1804599

10
标准的Hash类的new方法接受一个块。当试图访问不存在的键时,会调用此块。该块会传递Hash本身和所请求的键(两个参数),并应返回所请求键的值。
这可以用于创建自动扩展的哈希表,以及其他一些用途:
h = Hash.new{ |h,k| h[k] = 'default value'}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接