在Python中,可以读取字典/散列键,同时将键设置为默认值(如果尚不存在)。
例如:
>>> d={'key': 'value'}
>>> d.setdefault('key', 'default')
'value' # returns the existing value
>>> d.setdefault('key-doesnt-exist', 'default')
'default' # sets and returns default value
>>> d
{'key-doesnt-exist': 'default', 'key': 'value'}
是否有与Ruby哈希的等价物?如果没有,Ruby中的惯用方法是什么?
答案 0 :(得分:10)
Hash可以有默认值或默认Proc(当没有键时调用)。
h = Hash.new("hi")
puts h[123] #=> hi
# change the default:
h.default = "ho"
在上面的情况下,哈希保持为空。
h = Hash.new{|h,k| h[k] = []}
h[123] << "a"
p h # =>{123=>["a"]}
Hash.new([])
不起作用,因为每个键都使用相同的数组(与相同的对象相同)。
答案 1 :(得分:3)
不要在这里击败死马,但setDefault的行为更像是对哈希的fetch。它的行为与默认对哈希的作用方式不同。在哈希上设置默认值后,任何缺少的键都将使用该默认值。 setDefault不是这种情况。它仅存储一个缺失密钥的值,并且仅在找不到该密钥时才存储。整个存储新的键值对是它与fetch的不同之处。
与此同时,我们目前正在做setDefault的工作:
h = {}
h['key'] ||= 'value'
Ruby继续开车回家:
h.default = "Hey now"
h.fetch('key', 'default') # => 'value'
h.fetch('key-doesnt-exist', 'default') # => 'default'
# h => {'key' => 'value'}
h['not your key'] # => 'Hey now'
的Python:
h = {'key':'value'}
h.setdefault('key','default') # => 'value'
h.setdefault('key-doesnt-exist','default') # => 'default'
# h {'key': 'value', 'key-doesnt-exist': 'default'}
h['not your key'] # => KeyError: 'not your key'
答案 2 :(得分:2)
Python中没有与此功能等效的功能。您始终可以使用猴子修补来获得此功能:
class Hash
def setdefault(key, value)
if self[key].nil?
self[key] = value
else
self[key]
end
end
end
h = Hash.new
h = { 'key' => 'value' }
h.setdefault('key', 'default')
# => 'value'
h.setdefault('key-doesnt-exist', 'default')
# => 'default'
但请记住,猴子修补通常被视为禁忌,至少在某些代码环境中是这样。
猴子补丁的黄金法则适用:只因为你可以, 并不意味着你应该。
更惯用的方法是通过传递额外的块或值来通过Hash constructor定义默认值。
答案 3 :(得分:1)
您可以简单地pass a block to the Hash
constructor:
hash = Hash.new do |hash, key|
hash[key] = :default
end
当尝试访问不存在的密钥时,将调用该块。它将传递哈希对象和密钥。你可以随心所欲地做任何事情;将密钥设置为默认值,从密钥中导出新值等
如果您已有Hash
个对象,则可以使用the default_proc=
method:
hash = { key: 'value' }
# ...
hash.default_proc = proc do |hash, key|
hash[key] = :default
end
答案 4 :(得分:1)
如果您只想修改setdefault
返回的值,则可以通过Hash#merge!
来表示:
Python:
>>> d = {}
>>> d.setdefault("k", []).append("v")
>>> d
{'k': ['v']}
Ruby:
[28] pry(main)> h = {}
=> {}
[29] pry(main)> h.merge!(k: [:v]) { |_key, old, new| old.concat(new) }
=> {:k=>[:v]}
[30] pry(main)> h
=> {:k=>[:v]}