2013-11-03 22 views
13

Trong Python, tôi có thể tạo một băm trong đó mỗi phần tử có một giá trị mặc định khi nó được tham chiếu đầu tiên (còn được gọi là "tự động hóa"). Dưới đây là một ví dụ:Tương đương với Ruby của defaultdict của Python là gì?

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

In dict cho thấy giá trị cho "new_key" là 1.

tương đương trong Ruby là gì? Mã này ném một lỗi:

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

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

Trả lời

9

Bạn có thể sử dụng đối số đầu tiên của phương pháp Hash.new cho rằng:

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

Hãy cẩn thận - bạn có thể vô tình thay đổi giá trị mặc định:

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

Khi "mu quá ngắn" được chỉ ra trong câu trả lời của mình, bạn nên tốt hơn cho bạn một proc, như trong:

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

Làm thế nào để bạn tạo một hash với cả một giá trị mặc định và các phím ': unknown_key' và': next_key'? – rightfold

17

Bạn có thể gán giá trị mặc định sử dụng default=:

d.default = 0 

Lưu ý rằng điều này sẽ không thực sự autovivify tuy nhiên, nó chỉ làm cho d[:new_key] trở lại một số không mà không thực sự thêm một chìa khóa :new_key. default= cũng có thể gây ra sự cố nếu bạn định sửa đổi giá trị mặc định; điều đó có nghĩa là d.default = [ ] hầu như luôn là một sai lầm vì mảng sẽ không được sao chép khi truy cập mặc định được truy cập.

Một lựa chọn tốt hơn thường default_proc= là:

d.default_proc = proc { |h, k| h[k] = 0 } 

này cho phép bạn có giá trị mặc định riêng biệt và nó cho phép bạn thêm khóa mới (hay không tùy thuộc vào cách proc là có cấu trúc).

Bạn cũng có thể thiết lập các khi tạo Hash:

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

Điều này cần phải là câu trả lời được chấp nhận. –

+1

Tôi đồng ý. Tôi không thể xóa câu trả lời của mình, vì vậy tôi sẽ thêm ghi chú vào đó. – tessi

8

Các new phương pháp tiêu chuẩn cho Hash chấp nhận một khối. Khối này được gọi trong trường hợp cố gắng truy cập một khóa trong Hash mà không tồn tại. Khối được thông qua Hash và khóa được yêu cầu (hai tham số) và sẽ trả về giá trị cần trả về cho khóa được yêu cầu.

này có thể được sử dụng để tạo một hash autovivified, trong số những thứ khác:

h = Hash.new{ |h,k| h[k] = 'default value'} 
Các vấn đề liên quan