# 瞎扯淡 pythoner 砸场子来了

gaicitadie · 2012年03月19日 · 最后由 ShiningRay 回复于 2012年06月11日 · 12646 次阅读

``````>>> '11ab1111ab111ac11111'.count('ab')
2

``````
``````irb> '11ab1111ab111ac11111'.scan("ab").count
2

``````
``````1.9.2p290 :001 >  '11ab1111ab111ac11111'.count('ab')
=> 5

``````

Ruby 的 "".count 统计的是后面所有的字符

``````>>> sorted([('china',37,26,11), ('usa',30,22,50), ('russia',30,33,20)], key=lambda x:(-x[1],-x[2],-x[3]))
[('china', 37, 26, 11), ('russia', 30, 33, 20), ('usa', 30, 22, 50)]

``````

``````>>> sorted([('china',37,26,11), ('usa',30,22,50), ('russia',30,33,20)], key=lambda x:-(x[1]+x[2]+x[3]))
[('usa', 30, 22, 50), ('russia', 30, 33, 20), ('china', 37, 26, 11)]

``````

python 的排序达到了类似 SQL 查询的能力，只需要告诉它排序的条件就可以了，python 为数据而生

``````>>> [x for x in [('china',37,26,11), ('usa',30,22,50), ('russia',30,33,20)] if x[1]>35]
[('china', 37, 26, 11)]

``````

``````>>> [x for x in [('china',37,26,11), ('usa',30,22,50), ('russia',30,33,20)] if x[1]+x[2]+x[3]>100]
[('usa', 30, 22, 50)]

``````

``````[['china',37,26,11], ['usa',30,22,50], ['russia',30,33,20]].select{|x| x[1] > 35}
[['china',37,26,11], ['usa',30,22,50], ['russia',30,33,20]].select{|x| x[1] + x[2] + x[3] > 100}

``````

#6 楼 @gaicitadie order by 的 ruby 代码

``````[['china',37,26,11], ['usa',30,22,50], ['russia',30,33,20]].sort_by{|m| [-m[1], -m[2], -m[3]]}
[['china',37,26,11], ['usa',30,22,50], ['russia',30,33,20]].sort_by{|m| -(m[1] + m[2] + m[3])]}

``````

``````[['china',37,26,11], ['usa',30,22,50], ['russia',30,33,20]].sort_by{|x| [-x[1],-x[2],-x[3]]}

``````

2 美国习惯上金牌银牌铜牌都是奖牌，所以按奖牌总数排序：

``````[['china',37,26,11], ['usa',30,22,50], ['russia',30,33,20]].sort_by{|x| -(x[1]+x[2]+x[3])}

``````

3 统计金牌数超过 35 的国家：

``````[['china',37,26,11], ['usa',30,22,50], ['russia',30,33,20]].select{|x| x[1] >35}

``````

4 统计奖牌总数超过 100 的国家：

``````[['china',37,26,11], ['usa',30,22,50], ['russia',30,33,20]].select{|x| x[1]+x[2]+x[3] > 100}

``````

``````data = [[:china, 27, 26, 11], [:usa, 20, 22, 50], [:russia, 30, 33, 20]]

data.sort_by { |x| [-x[1], -x[2], -x[3]] } # 中国排序方法，按金/银/铜牌数
data.sort_by { |x| -(x[1] + x[2] + x[3]) } # 美国排序方法，按奖牌总数

``````

``````data.select { |x| x[1] > 35 } # 金牌数超过35的国家
data.select { |x| x[1] + x[2] + x[3] > 100 } # 奖牌总数超过100的国家

``````

#10 楼 @skandhas 看了你的方法，才想到，select 是更直接的做法。collect 方法会包含 nil 值。

``````['Jim', 'bush', 'Jim', 'Jim', 'Jim', 'bush', 'obama']

``````

``````>>> l = ['Jim', 'bush', 'Jim', 'Jim', 'Jim', 'bush', 'obama']
>>> sorted(set([(i, l.count(i)) for i in l]), key=lambda x:-x[1])
[('Jim', 4), ('bush', 2), ('obama', 1)]

``````

#16 楼 @clearJiang 低版本没有 collections

``````l = ['Jim', 'bush', 'Jim', 'Jim', 'Jim', 'bush', 'obama']
l.uniq.collect { |x| [x, l.count(x)] }
=> [["Jim", 4], ["bush", 2], ["obama", 1]]

``````

``````l = ['Jim', 'bush', 'Jim', 'Jim', 'Jim', 'bush', 'obama']
l.group_by{|i| i}.map{|k,v| [k,v.length] }

``````

python 要和 ruby 比 文件、字符操作或者数组、Hash 操作的便利性绝对完败，要砸场还不如在性能上一棍子打死 ruby。

``````['Jim', 'bush', 'Jim', 'Jim', 'Jim', 'bush', 'obama'].inject(Hash.new(0)) {|h, e| h[e] += 1; h}.sort_by{|e| -e[1]}

``````

``````>>> import random
>>> s = 'ABCDEFGHIJKLMNPRSTUVWXYZ'
>>> ''.join(random.sample((s),4))
'EXSG'
>>> ''.join(random.sample((s),4))
'TGYN'
>>> ''.join(random.sample((s),4))
'MEYP'
>>> ''.join(random.sample((s),4))
'TGIF'
>>> ''.join(random.sample((s),4))
'JDWF'

``````
``````('A'..'Z').to_a.sample(4).join

``````

#15 楼 @gaicitadie 你这个算法是 O(n ^ 2) 的，应该用 reduce

``````def stat(acc, x):
acc.setdefault(x, 0)
acc[x] += 1
return acc
sorted(reduce(stat,
['Jim', 'bush', 'Jim', 'Jim', 'Jim', 'bush', 'obama'], {}).iteritems(),
key = lambda x: -x[1])

``````

@skandhas cool，加上个排序。

#26 楼 @reus reduce 不如列表解析快，虽然 list.count 会重复统计

#27 楼 @huyong36 对，是忘了排序

``````l = ['Jim', 'bush', 'Jim', 'Jim', 'Jim', 'bush', 'obama']
l.group_by{|i| i}.map{|k,v| [k,v.length] }.sort_by{|name,count| -count }

``````

#28 楼 @gaicitadie 就是慢在 count 调用上，for i in l 遍历数组，且每个元素又再 count 遍历一次，O(n ^ 2) reduce 只需要遍历一次，O(n) 不信可以测试下

• 字符串查找
``````# python
>>> '11ab1111ab111ac11111'.count('ab')
2
# Ruby
ruby-1.9.2-p290 >   '11ab111123ab111ac11111'.count 'ab', 'b'
2

``````
• 奖牌排序
``````# python
>>> sorted([('china',37,26,11), ('usa',30,22,50), ('russia',30,33,20)], key=lambda x:(-x[1],-x[2],-x[3]))
[('china', 37, 26, 11), ('russia', 30, 33, 20), ('usa', 30, 22, 50)]
# ruby
ruby-1.9.2-p290 > [['china',37,26,11], ['usa',30,22,50],['russia',30,33,20]].sort_by {|name,j,y,t| [-j,-y,-t] }
=> [["china", 37, 26, 11], ["russia", 30, 33, 20], ["usa", 30, 22, 50]]

``````
• 奖牌统计
``````# python
>>> sorted([('china',37,26,11), ('usa',30,22,50), ('russia',30,33,20)], key=lambda x:-(x[1]+x[2]+x[3]))
[('usa', 30, 22, 50), ('russia', 30, 33, 20), ('china', 37, 26, 11)]
# ruby
ruby-1.9.2-p290 > [['china',37,26,11], ['usa',30,22,50],['russia',30,33,20]].sort_by {|name,j,y,t| [-j + -y + -t] }
=> [["usa", 30, 22, 50], ["russia", 30, 33, 20], ["china", 37, 26, 11]]

``````

``````'11ab1111ab111ac11111'.match(/ab/g).length;

``````
``````'11ab1111ab111ac11111'.split('ab').length - 1;

``````

``````[[37, 26, 11], [30, 22, 50], [30, 33, 20]].sort().reverse();

``````

``````# ruby
>>> l = ['Jim', 'bush', 'Jim', 'Jim', 'Jim', 'bush', 'obama']
>>> sorted(set([(i, l.count(i)) for i in l]), key=lambda x:-x[1])
[('Jim', 4), ('bush', 2), ('obama', 1)]
# ruby
ruby-1.9.2-p290 >  ['bush','Jim', 'bush', 'Jim', 'Jim', 'Jim', 'bush', 'obama'].each_with_object({}) {|name,s| s[name] = s.fetch(name,0) + 1 }.sort
=> [["Jim", 4], ["bush", 3], ["obama", 1]]
``````
``````'11ab111123ab111ac11111'.count 'ab', 'b'

``````

``````irb(main):106:0> '11ab111123ab111ac11111b'.count 'ab', 'b'
=> 3

``````

@huyong36 thx count 是没办法实现的，别的方法也不错

#40 楼 @hysios 恩，请教

``````irb(main):115:0> '11ab111123ab111c11111'.count  'a'
=> 2
irb(main):114:0> '11ab111123ab111c11111'.count  'ab'
=> 4

``````

@huyong36 count([other_str]+) → fixnum click to toggle source Each other_str parameter defines a set of characters to count. The intersection of these sets defines the characters to count in str. Any other_str that starts with a caret (^) is negated. The sequence c1–c2 means all characters between c1 and c2.

``````gaicitadie = [['china',37,26,11], ['usa',30,22,50], ['russia',30,33,20]].tap do |man|
def man.make_self(&process); process.call self; end
`python -c "print( sorted([('china',37,26,11), ('usa',30,22,50), ('russia',30,33,20)], key=lambda x:(-x[1],-x[2],-x[3])) )"`
end
def man.glow_up
dont_be_shy = true
unless self.respond_to? :more_elegant, dont_be_shy
def self.more_elegant
self.sort_by { |country, glods, silvers, bronzes| [-glods,-silvers,-bronzes] }
end
end
class << self; remove_method :become_egghead; end
end
self
end
end

``````

#41 楼 @huyong36 ruby 的 count 统计的是字符的数量 所以`'11ab111123ab111c11111'.count 'ab'`等同于`'11ab111123ab111c11111'.count 'a'` + `'11ab111123ab111c11111'.count 'b'`

#41 楼 @huyong36 count 是统计所有的字符，并不会把参数当成字符串处理

``````hash1.merge(hash2) {|dupkey,val1,val2| val1 + val2 }

``````

method_missing, 楼主来个？？

#48 楼 @FenRagwort ，这个暂时只想到了普通方法

``````for k,v in hash2.items():
if k in hash1:
hash1[k] += v
else:
hash1.setdefault(k,v)

``````

``````class Foo:
def __getattr__(self, name):
def _foo(*arg, **kwargs):
return self.method_missing(name, *arg, **kwargs)
return _foo

def method_missing(self, name, *args, **kwargs):
print name, args, kwargs

a = Foo()
a.foo('bar', baz = 'baz')

``````

``````ruby-1.9.2-p290 >   '11ab111123ab111ac11111b'.count 'ab', 'b'

``````

``````a=[]
h={}
"{'a':'va','b':'vb','c':'vc'}".gsub(/([\w+\d+]+)/) {|s| a+=s.to_a}
a.each{|x| h.store(x,a[a.index(x)+1]) if a.index(x)%2==0}
h
=> {"c"=>"vc", "b"=>"vb", "a"=>"va"}

``````

#55 楼 @jhjguxin 是想转换成 hash 吗？把：替换成=>,然后 eval 不行吗？

``````eval "{'a':'va','b':'vb','c':'vc'}".gsub(':','=>')

``````

``````require 'json'
wtf = "{'a':'va','b':'vb','c':'vc'}".gsub("'",'"')
JSON.parse wtf
# => {"a"=>"va", "b"=>"vb", "c"=>"vc"}

``````

#58 楼 @fredwu 用 json 库，恩，学习了。thx！

@fredwu 不是胡闹 是新手 还想不出来 有这些方法 学习了哈 ps 觉得可以把这个楼 盖起来 楼下的说好不好