相当于Ruby中的Python计数器

时间:2015-11-20 13:54:58

标签: python ruby

Python在collections模块中有Counter个类。它是一个用于计算可清除对象的类。 E.g:

cnt = Counter()
cnt['Anna'] += 3
cnt['John'] += 2
cnt['Anna'] += 4
print(cnt)
=> Counter({'Anna': 7, 'John': 2})
print(cnt['Mario'])
=> 0

Ruby中Counter的等价物是什么?

修改

Counter类还提供以下数学运算和辅助方法:

c = Counter(a=3, b=1)
d = Counter(a=1, b=2)
c + d 
=> Counter({'a': 4, 'b': 3})
c - d
=> Counter({'a': 2})
c.most_common(1)
=> ['a']

3 个答案:

答案 0 :(得分:4)

cnt = Hash.new(0)
cnt["Anna"] += 3
cnt["John"] += 2
cnt["Anna"] += 4
cnt # => {"Anna" => 7, "John" => 2}
cnt["Mario"] #=> 0

c = {"a" => 3, "b" => 1}
d = {"a" => 1, "b" => 2}
c.merge(d){|_, c, d| c + d} # => {"a" => 4, "b" => 3}
c.merge(d){|_, c, d| c - d}.select{|_, v| v > 0} # => {"a" => 2}
c.max(1).map(&:first) # => ["a"]

答案 1 :(得分:2)

这是一个小实现:

class Counter < Hash
  def initialize(other = nil)
    super(0)
    if other.is_a? Array 
      other.each { |e| self[e] += 1 }
    end
    if other.is_a? Hash
      other.each { |k,v| self[k] = v }
    end
    if other.is_a? String
      other.each_char { |e| self[e] += 1 }
    end
  end
  def +(rhs)
     raise TypeError, "cannot add #{rhs.class} to a Counter" if ! rhs.is_a? Counter  
     result = Counter.new(self)
     rhs.each { |k, v| result[k] += v }
     result
  end
  def -(rhs)
     raise TypeError, "cannot subtract #{rhs.class} to a Counter" if ! rhs.is_a? Counter  
     result = Counter.new(self)
     rhs.each { |k, v| result[k] -= v }
     result
  end
  def most_common(n = nil)
     s = sort_by {|k, v| -v}
     return n ? s.take(n) : s
  end
  def to_s
     "Counter(#{super.to_s})"
  end
  def inspect
     to_s
  end
end

支持

  • 从字符串,数组和散列构造
  • 访问和修改计数
  • 两个计数器的加法和减法
  • 访问most_common元素

c1 = Counter.new([1,0,1])   #=> Counter({1=>2, 0=>1})
c1[2] = 1                   #=> 1 
c1                          #=> Counter({1=>2, 0=>1, 2=>1})
c2 = Counter.new([3,1])     #=> Counter({3=>1, 1=>1})
c1 + c2                     #=> {1=>3, 0=>1, 2=>1, 3=>1}
c3 = Counter.new("abraca")  #=> {"a"=>3, "b"=>1, "r"=>1, "c"=>1}
c3.most_common(2)           #=> [["a", 3], ["b", 1]]

答案 2 :(得分:-1)

计数器是一个非常奇怪且非常误导的名称。其他人称之为Multiset。在Ruby核心或标准库中没有多集实现,但是在Web上有一些实现: