什么是Ruby相当于Python的defaultdict?

Oll*_*ass 17 ruby python dictionary language-comparisons autovivification

在Python中,我可以创建一个散列,其中每个元素在首次引用时都具有默认值(也称为"autovivification").这是一个例子:

from collections import defaultdict
d = defaultdict(int)
d["new_key"] += 1
print d
Run Code Online (Sandbox Code Playgroud)

打印dict显示"new_key"的值为1.

Ruby中的等价物是什么?此代码抛出错误:

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

test.rb:3:in `<main>': undefined method `+' for nil:NilClass (NoMethodError)
Run Code Online (Sandbox Code Playgroud)

mu *_*ort 23

您可以使用default=以下方式指定默认值:

d.default = 0
Run Code Online (Sandbox Code Playgroud)

请注意,这不会真正自动生成,它只是在d[:new_key]没有实际添加:new_key密钥的情况下返回零.default=如果您打算修改默认值,也会导致问题; 这意味着d.default = [ ]几乎总是一个错误,因为访问默认值时不会复制数组.

通常更好的选择是default_proc=:

d.default_proc = proc { |h, k| h[k] = 0 }
Run Code Online (Sandbox Code Playgroud)

这允许您具有不同的默认值,并允许您添加新键(或不取决于proc结构的方式).

您还可以在创建哈希时设置这些:

d = Hash.new(0)
d = Hash.new { |h, k| h[k] = 0 }
Run Code Online (Sandbox Code Playgroud)

  • 这需要是公认的答案. (2认同)

tes*_*ssi 14

您可以使用该Hash.new方法的第一个参数:

d = Hash.new 0
d[:new_key] += 1
d[:new_key] #=> 1
d[:foo]     #=> 0
Run Code Online (Sandbox Code Playgroud)

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

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

由于在他的回答中指出"mu太短",你应该更好地使用proc,如:

h = Hash.new { |h, k| h[k] = 0 }
Run Code Online (Sandbox Code Playgroud)


Mar*_*mas 9

newHash 的标准方法接受块.如果尝试访问Hash中不存在的密钥,则调用此块.该块传递Hash本身和请求的密钥(两个参数),并应返回应为请求的密钥返回的值.

这可用于创建自动生成的哈希,以及其他内容:

h = Hash.new{ |h,k| h[k] = 'default value'}
Run Code Online (Sandbox Code Playgroud)