やるきなし

2017/09/28 15:48 / Ruby and Python

Assuming python3.

Multi-line comments

Ruby

=begin
Comment.
=end

Python

'''
Comment.
'''

If statements with regular expression

Ruby

i='hoge'
if i=~/^h/
    print i,"\n"
end

Python

import re
i='hoge'
if re.search(r'^h',i):
    print(i)

Python (search() vs. match())

>>> import re
>>> i='hoge'
>>> re.match(r'h',i)
<_sre.SRE_Match object; span=(0, 1), match='h'>
>>> re.search(r'h',i)
<_sre.SRE_Match object; span=(0, 1), match='h'>
>>> re.match(r'g',i)
>>> re.search(r'g',i)
<_sre.SRE_Match object; span=(2, 3), match='g'>

If statements with regular expression 2

Ruby

i='hoge 100'
if i=~/\s+(\d+)/
    print $1,"\n"
end

Python

import re
i='hoge 100'
r=re.search(r'\s+(\d+)', i)
if r:
    print(r.groups()[0])

Note that python's assignment is not expression but statement. So the following causes SyntaxError.

if r=re.search(r'\s+(\d+)', i):
    print(r.groups()[0])

Matched object and string-to-integer conversion

Ruby

i='0,11,22'
i.scan(/\d+/).map{|j| j.to_i}

i='0,11,22'
i.scan(/\d+/).map &:to_i

Python

import re
i='0,11,22'
list(map(int,re.findall(r'\d+',i)))

import re
i='0,11,22'
[int(j) for j in re.findall(r'\d+',i)]

Split by regular expressions

Ruby

i='0-11,22'
i.split(/[-,]/)

Python

import re
i='0-11,22'
re.split(r'[-,]',i)

And more

Ruby

irb(main):001:0> '0-11,22'.split(/[-,]/).map{|j| j.to_i}
=> [0, 11, 22]
irb(main):002:0> '0-11,22'.split(/[-,]/).map(&:to_i)
=> [0, 11, 22]
irb(main):003:0> '0-11,22'.split(/[-,]/).map(&:to_i).inject(0){|sum,j| sum+j}
=> 33
irb(main):004:0> '0-11,22'.split(/[-,]/).map(&:to_i).inject{|sum,j| sum+j}
=> 33
irb(main):005:0> '0-11,22'.split(/[-,]/).map(&:to_i).inject(0,:+)
=> 33
irb(main):006:0> '0-11,22'.split(/[-,]/).map(&:to_i).inject(:+)
=> 33
irb(main):007:0> '0-11,22'.split(/[-,]/).map(&:to_i).reduce(:+)
=> 33

Note that reduce is an alias of inject. sum method for Array is available in Ruby 2.4.

Python3

>>> import re
>>> map(int,re.split(r'[-,]','0-11,22'))
<map object at 0x7fc0dfe171d0>
>>> list(map(int,re.split(r'[-,]','0-11,22')))
[0, 11, 22]
>>> [int(x) for x in re.split(r'[-,]','0-11,22')]
[0, 11, 22]
>>> int
<class 'int'>
>>> sum(map(int,re.split(r'[-,]','0-11,22')))
33
>>> sum(list(map(int,re.split(r'[-,]','0-11,22'))))
33

Python2

>>> import re
>>> map(int,re.split(r'[-,]','0-11,22'))
[0, 11, 22]
>>> list(map(int,re.split(r'[-,]','0-11,22')))
[0, 11, 22]
>>> [int(x) for x in re.split(r'[-,]','0-11,22')]
[0, 11, 22]
>>> int
<type 'int'>
>>> sum(map(int,re.split(r'[-,]','0-11,22')))
33
>>> sum(list(map(int,re.split(r'[-,]','0-11,22'))))
33

YAML

Ruby

irb(main):001:0> i=[['a','b'],['c','d']]
=> [["a", "b"], ["c", "d"]]
irb(main):002:0> require "yaml"
=> true
irb(main):003:0> print YAML.dump(i)
---
- - a
  - b
- - c
  - d
=> nil

Python

>>> i=[['a','b'],['c','d']]
>>> import yaml
>>> print(yaml.dump(i), end="")
- [a, b]
- [c, d]
>>> print(yaml.dump(i, default_flow_style = False), end="")
- - a
  - b
- - c
  - d

In case of UTF-8, `allow_unicode = True' is required for dump().

Character translation

Ruby

irb(main):001:0> i='hoge'
=> "hoge"
irb(main):002:0> i.tr('he','HE')
=> "HogE"

Python

>>> i='hoge'
>>> i.translate(str.maketrans("he", "HE"))
'HogE'

Join

Ruby

irb(main):001:0> i=[0,1,2]
=> [0, 1, 2]
irb(main):002:0> i*","
=> "0,1,2"
irb(main):003:0> i.join(',')
=> "0,1,2"

Python

>>> i=[0,1,2]
>>> ','.join([str(j) for j in i])
'0,1,2'

Hash/Dictionary

Ruby

irb(main):001:0> i=[['a','b'],['c','d']]
=> [["a", "b"], ["c", "d"]]
irb(main):002:0> h=Hash[i]
=> {"a"=>"b", "c"=>"d"}
irb(main):003:0> h.each{|key,val| print "#{key}: #{val}","\n"}
a: b
c: d
=> {"a"=>"b", "c"=>"d"}
irb(main):004:0> h.each{|j| print j*": ","\n"}
a: b
c: d
=> {"a"=>"b", "c"=>"d"}
irb(main):005:0> h.keys.each{|key| print "#{key}: #{h[key]}","\n"}
a: b
c: d
=> ["a", "c"]

Python

>>> i=[['a','b'],['c','d']]
>>> d=dict(i)
>>> d
{'a': 'b', 'c': 'd'}
>>> for i in d: print(i)
c
a
>>> for i in d.items(): print(i)
('c', 'd')
('a', 'b')
>>> for i in sorted(d): print(i)
a
c
>>> for i in sorted(d.items()): print(i)
('a', 'b')
('c', 'd')
>>> for key,val in sorted(d.items()): print(key+": "+val)
a: b
c: d

Regular expression options

Ruby

irb(main):001:0> "Hoge\nhoge".scan(/^h.*/)
=> ["hoge"]
irb(main):002:0> "Hoge\nhoge".scan(/^h.*/i)
=> ["Hoge", "hoge"]
irb(main):003:0> "Hoge\nhoge".scan(/^h.*/im)
=> ["Hoge\nhoge"]
irb(main):004:0> "Hoge\nhoge".scan(/\Ah.*/i)
=> ["Hoge"]

i: ignore case, m: multiline (. matches '\n').

^ matches at the beginning of each line.

\A matches beginning of string.

Python

>>> import re
>>> re.findall(r'^h.*', 'Hoge\nhoge')
[]
>>> re.findall(r'^h.*', 'Hoge\nhoge', re.M)
['hoge']
>>> re.findall(r'^h.*', 'Hoge\nhoge', re.M | re.I)
['Hoge', 'hoge']
>>> re.findall(r'^h.*', 'Hoge\nhoge', re.M | re.I | re.S)
['Hoge\nhoge']

M(MULTILINE): multline (^ matches at the beginning of each line), I(IGNORECASE): ignore cases, S(DOTALL): also multiline (. matches any character at all).

Ruby's gsub

Ruby

irb(main):001:0> "abc".gsub(/^(.)/){ $1+"." }
=> "a.bc"

Python

>>> import re
>>> re.sub(r'^(.)',r'\1.',"abc")
'a.bc'

Embedding expressions in string

Ruby

irb(main):001:0> a=[10,20,30]
=> [10, 20, 30]
irb(main):002:0> "hoge: #{a[0]}"
=> "hoge: 10"
irb(main):003:0> "hoge: #{a[0]+100}"
=> "hoge: 110"

Python

>>> a=[10,20,30]
>>> "hoge: {a[0]}".format(**locals())
'hoge: 10'

Command line arguments

Ruby

% ruby -e 'p ARGV' 0 1
["0", "1"]

Python

% python3 -c 'import sys; print(sys.argv)' 0 1
['-c', '0', '1']

Command execution (backticks in ruby/shell)

Ruby

print(`ls -l`)
print(%x{ls -l})
print(%x!ls -l!)

Python

import os
print(os.popen('ls -l').read(),end="")

File/directory check

Ruby

irb(main):001:0> File.exist?('Makefile')
=> true
irb(main):002:0> File.file?('Makefile')
=> true
irb(main):003:0> File.exist?('src')
=> false
irb(main):004:0> `mkdir src`
=> ""
irb(main):005:0> File.exist?('src')
=> true
irb(main):006:0> File.directory?('src')
=> true

Python

>>> import os
>>> os.path.exists('Makefile')
True
>>> os.path.isfile('Makefile')
True
>>> os.path.exists('src')
False
>>> os.popen('mkdir src')

>>> os.path.exists('src')
True
>>> os.path.isdir('src')
True

glob

Ruby

Dir.glob("*").each{|i| p i}

Python

import glob
for i in glob.glob("*"):
    print(i)

Array/List

Ruby

irb(main):001:0> a=[]
=> []
irb(main):002:0> a.empty?
=> true
irb(main):003:0> a << 0
=> [0]
irb(main):004:0> a += [1,2,3]
=> [0, 1, 2, 3]
irb(main):005:0> a.empty?
=> false
irb(main):006:0> a.delete_if{|i| i==0}
=> [1, 2, 3]
irb(main):007:0> a
=> [1, 2, 3]

Python

>>> a=[]
>>> not a
True
>>> a.append(0)
>>> a
[0]
>>> a.extend([1,2,3])
>>> a
[0, 1, 2, 3]
>>> not a
False
>>> [i for i in a if not i == 0]
[1, 2, 3]

Double colon (::) in python

Pytnon

>>> a=list(range(16))
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
>>> a[::2]
[0, 2, 4, 6, 8, 10, 12, 14]
>>> a[::3]
[0, 3, 6, 9, 12, 15]
>>> a[1::3]
[1, 4, 7, 10, 13]
>>> a[2::3]
[2, 5, 8, 11, 14]
>>> a[10::3]
[10, 13]
>>> a[10::-1]
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
>>> a[10::-2]
[10, 8, 6, 4, 2, 0]
>>> a[10::-3]
[10, 7, 4, 1]

More precisely, a[i:j:k] means slice of a from i to j with step k. Double colon (::) just appears when j is omitted. Note that i and k also can be omitted.

Ruby

irb(main):001:0> a=(0...16).to_a
=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
irb(main):002:0> a.each_slice(2).map(&:first)
=> [0, 2, 4, 6, 8, 10, 12, 14]
irb(main):003:0> a[1..-1].each_slice(2).map(&:first)
=> [1, 3, 5, 7, 9, 11, 13, 15]
irb(main):004:0> (0...16).step(2).to_a
=> [0, 2, 4, 6, 8, 10, 12, 14]
irb(main):005:0> 0.step(15,2).to_a
=> [0, 2, 4, 6, 8, 10, 12, 14]

// in python

Pytnon

>>> 101/2
50.5
>>> 101//2
50

Ruby

> 101.to_f/2
=> 50.5
> 101/2
=> 50
> //.class
=> Regexp

mkdir -p (recursive mkdir and no error if existing)

Ruby

irb(main):001:0> require 'fileutils'
=> true
irb(main):002:0> FileUtils.mkdir_p("foo/bar/")
=> ["foo/bar/"]

Python

>>> import os
>>> os.makedirs("foo/bar/",exist_ok=True)

pythons's defaultdict

Ruby

a=Hash.new{|h,k| h[k]=[]}
(0..2).each{|i| a[i]<< i}
p a

output:

{0=>[0], 1=>[1], 2=>[2]}

Python

from collections import defaultdict
a=defaultdict(list)
for i in range(3):
  a[i].append(i)
from pprint import pprint
pprint(a)

output:

defaultdict(<class 'list'>, {0: [0], 1: [1], 2: [2]})