Note that writing like this with ruby is writing like this with python

I'm used to ruby and not python, but I have more opportunities to write python, so it feels like a memorandum.

Python is completely new to me. python 3. I decided not to care about python 2.x.

Processing system at hand

Confirmed in

length

ruby


ary_len = [1,2,3].size # [1,2,3].length is fine
hash_len = {a:1}.size # {a:1}.length is fine
string_len = "hoge".size # "hoge".length is fine

range_len = (1..9).size # Range#There is no length.

python3


ary_len = len([1,2,3])
dic_len = len({"a":1})
string_len = len("hoge")
range_len = len(range(1,10)) # 1〜9

Well this area is easy.

Around Object

Mold

ruby


[].class #=> Array
1.class #=> Integer
[].is_a?(Enumerable) #=> true
Enumerable===[] #=> true
Enumerable==="" #=> false
[1,1.0,1r,1i].map{ |x| x.is_a?( Numeric ) } #=> [true, true, true, true]

python3


type([]) #=> <class 'list'>
type(1) #=> <class 'int'>

The process that seems to correspond to ruby's ʻEnumerable` is as follows:

python3


from collections import Iterable
isinstance([], Iterable) #=> True
isinstance("", Iterable) #=> True

Note that the ruby string is not Enumerable, but the python string is Iterable.

Below is an example of using a class like Numeric in ruby in python:

python3


from numbers import Number
[isinstance(x,Number) for x in [1.0, 1, ""]] #=> [True,True,False]

Number and Iterable. Does that mean that importing will give you access to the name of the base class?

Duplicate

ruby


copied = [1,2,3].dup

python3


import copy
copied = copy.copy([1,2,3])

Python requires import to duplicate common objects. However, you can use the following idioms, methods, and constructors to copy the list:

python3


copied1 = [1,2,3][:] #Maybe this is normal.
copied2 = [1,2,3].copy()
copied3 = list([1,2,3]) #Maybe the constructor

dict also has a copy method:

python3


copied = {1:2}.copy()
copied = dict({1:2}) #Maybe the constructor

However. numpy's array is [:] and cannot be copied.

import numpy as np
a=np.array([1,2,3])
b=a[:]
b[2]=100
print(a) #=> [  1   2 100]

It's a trap. If you want to copy, use the copy method like b = a.copy () or use the constructor.

Comparison

ruby


[]==[] #=>true ordinary comparison
[].equal?([]) #=>false Whether it points to the same object

python3


[]==[] #=>true ordinary comparison
[] is [] #=>false Whether it points to the same object

Stringification

ruby


"hoge".to_s #=> 「hoge」
"hoge".inspect #=> 「"hoge"」
65.chr #=> "A"

python3


str("hoge") #=>「hoge」
repr("hoge") #=> 「'hoge'」
chr(65) #=> "A"

Around Array

Convert from range to list / array

ruby


(1..10).to_a #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[*1..10] #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

python3


list(range(1,11)) #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Take out the part

ruby


[*10..100][10,3] #=> [20, 21, 22]
[*10..100][10..12] #=> [20, 21, 22]

python3


list(range(10,101))[10:13] #=> [20, 21, 22]

I wonder if there is any other way to write it.

Part change

ruby


a=[*1..5]
a[2,2]=9 # a[2,2]=[9]But the same.
a # => [1, 2, 9, 5]

python3


a=list(range(1,6))
a[2:4]=[9] # a[2:4]=Can't write 9
a #=> [1, 2, 9, 5]

There are various ways to write ruby, such as ʻa [2,2] = 9or ʻa [2..3] = [9], but python is only one of the above.

last

ruby


[1,2,3][-1] #=> 3
[1,2,3].last #=> 3
[1,3,5,7,9].last(2) #=> [7, 9]

python3


[1,2,3][-1] #=> 3
[1,3,5,7,9][-2:] #=> [7,9]

There doesn't seem to be a last method in python.

push / unshift

ruby


a=[1,2,3]
a.push 9
a.unshift 8
a #=> [8,1,2,3,9]

python3


a=[1,2,3]
a.append(9)
a.insert(0,8)
a #=> [8,1,2,3,9]

It seems that python doesn't have a dedicated method to add to the beginning.

pop / shift

ruby


a=[1,2,3,4]
b = a.pop
c = a.shift
[ a, b, c ] #=> [[2, 3], 4, 1]

d=[1,2,3,4]
e=d.pop(2) #Move the first two to e
[d,e] #=> [[1,2],[3,4]]

python3


a=[1,2,3,4]
b = a.pop()
c = a.pop(0)
[ a, b, c ] #=> [[2, 3], 4, 1]

d=[1,2,3,4]
e=d[-2:]
d[-2:]=[]
[d,e] #=> [[1,2],[3,4]]

In python, pop has an argument of where to get it, and if you specify 0, it will behave as shift. The python d [-2:] = [] can be del d [-2:].

It seems that python does not have a method equivalent to ruby's d.pop (2).

map

ruby


[1,2,3].map{ |x| x*2 } #=> [2,4,6]
%w( 1 2 3 ).map(&:to_i) #=> [1,2,3]

python3


[x*2 for x in [1,2,3]] #=> [2,4,6]
list(map(int,["1","2","3"])) #=>[1,2,3]

inject / reduce

ruby


[1,2,3].inject(0){ |acc,x| acc+x } #=> 6
[1,2,3].inject(0, &:+) #=> 6

python3


import functools
functools.reduce(lambda x,y:x+y, [1,2,3], 0) #=> 6
functools.reduce(int.__add__, [1,2,3], 0) #=> 6

In the above example, it is better to use ʻoperator.add instead of ʻint.__ add__.

special thanks to antimon2: see http://qiita.com/Nabetani/items/50b0f6533a15d8fb2ae5#comment-bb3beb6fe012b4ebefe6

select

ruby


[1,2,3,4].select{ |x| x.even? } #=> [2, 4]

python3


[x for x in [1,2,3,4] if x%2==0 ] #=>[2, 4]

Maximum value

ruby


[1,5,13,21].max #=> 21
[1,5,13,21].max_by{ |x| x % 10 } #=> 5

python3


max([1,5,13,21]) #=> 21
max([1,5,13,21],key=lambda x:x%10 ) #=> 5

flatten

ruby


[1,[[2,3],4],5].flatten #=> [1,2,3,4,5]

There seems to be no flatten in python. see http://d.hatena.ne.jp/xef/20121027/p2

uniq

ruby


%w( f o o b a r b a z ).uniq #=>  ["f", "o", "b", "a", "r", "z"]

python3


list(set("foobarbaz")) #=> ['z', 'f', 'b', 'a', 'o', 'r']The order is not saved

If you want to save the order, use Python Tips: I want to remove duplicate elements from the list.

Non-destructive sort

ruby


[1,5,13,20].sort_by{ |x| x%10 } #=> [20,1,13,5]

python3


sorted([1,5,13,20], key=lambda x:x % 10 ) #=> [20, 1, 13, 5]

python sort is stable. ruby sort is not stable.

Reverse order

ruby


a=[1,3,5,7]
a.reverse #=> [7,5,3,1]Non-destructive
a.reverse! #Destructively reverse order
a #=> [7,5,3,1]

python3


a=[1,3,5,7]
list(reversed(a)) #=>[7, 5, 3, 1]Non-destructive
a[::-1] #=> [7, 5, 3, 1]Non-destructive
a.reverse() #Destructively reverse order
a #=> [7,5,3,1]

An amateur can't think of " :: -1 ". Note that the return value of reversed is list_reverseiterator, not list.

zip

ruby


[1,2,3].zip(%w(a b c)) #=> [[1, "a"], [2, "b"], [3, "c"]]
[1,2,3].zip(%w(a b)) #=> [[1, "a"], [2, "b"], [3, nil]]

python3


list(zip([1,2,3],["a","b","c"])) #=> [(1, 'a'), (2, 'b'), (3, 'c')]
list(zip([1,2,3],["a","b"])) #=> [(1, 'a'), (2, 'b')]

ruby is matched to the receiver. python is adapted to the shorter one.

python doesn't become a list just by zip. If you pass it to the constructor of list, it will be a list of tuples.

random number

sampling

ruby


[1,2,3].sample #=> 1 or 2 or 3
[1,3,5].sample(2) #=> [5,3], [1,5]Such. Not duplicate.

python3


import random
random.choice( [1,2,3] ) #=> 1 or 2 or 3
random.sample( [1,3,5], k=2 ) #=> [5,3], [1,5]Such. Not duplicate.

Floating point number between 0 and 1

ruby


rand

python3


import random
random.random()

Integer greater than or equal to 0 and less than 10

ruby


rand(10)

Or

ruby


rng=Random.new
rng.rand(10)
rng.rand(0..9)
rng.rand(0...10)

python3


import random
random.randint(0,9)

The range specification of python includes both ends.

Control structure

if statement

ruby


a=if 1.even?
  "foo"
elsif 1.odd?
  "bar"
else
  "baz"
end

python3


if 1%2==0:
    a="foo"
elif 1%2==1:
    a="bar"
else:
    a="baz"

In python, unlike ruby, if statements have no value. ruby's ʻelsif is python's ʻelif. Also, there is no postfix if.

case〜when

Python has no control structure equivalent to case ~ when or switch ~ case.

repetition

ruby


10.times do |num|
  do_something
end

loop do #infinite loop
  break if some_condition
end

python3


for num in range(10):
  do_something()

while True: #infinite loop
  if some_condition():
    break

literal

In general, ruby has a lot of literals, but python doesn't (compared to ruby).

Rational number

ruby


a=1.3r #=> (13/10)

python3


import fractions
fractions.Fraction(13,10) #=> 13/Value equivalent to 10

Rational number literals are not in python.

Regular expressions

ruby


/.\s./.match("hello, world")[0] #=> ", w"

python3


import re
re.search( r".\s.", "hello, world" ).group(0) #=> ', w'

Regular expression literals are not in python. r "" is r, which means raw string.

Expression expansion in string literals

ruby


"3**10=#{3**10}" #=>  "3**10=59049"

python3


"3**10=%d" % 3**10 #=>  "3**10=59049"

There is no expression expansion in python (it seems to be in 3.6. special thanks to norioc). You need to do something like printf.

Input / output

Buffer flush

ruby


print("hoge")
$stdout.flush()
print("hoge", end="", flush=True)

ʻImport sys may be sys.stdout.flush () `.

print and puts

ruby


print("hoge") #=>Output without trailing newline
puts("hoge") #=>Output with a newline at the end

python3


print("hoge", end="") #=>Output without trailing newline
print("hoge") #=>Output with a newline at the end

Existence of files and directories

File.exist?("foo") #=>true if foo is file or directory
File.file?("foo") #=>true if foo is file
File.directory?("foo") #=>true if foo is directory

python3


import os
os.path.exists("foo") #=>true if foo is file or directory
os.path.isfile("foo") #=>true if foo is file
os.path.isdir("foo") #=>true if foo is directory

~~ python doesn't seem to have a method equivalent to ruby's File.exist?. ~~ I was unaware that there was os.path.exists. Thank you, @tokyo_gs.

File open / close

ruby


a=File.open("hoge.txt"){ |f| f.read(10) }

python3


with open("hoge.txt") as f:
    a=f.read(10)

Python will automatically close the file when you use with.

Writing to a file.

Assuming that f is a file that can be taken with ʻopen`:

ruby


f.puts("hoge") #Newline at the end
f.print("fuga") #No line break at the end
f.write("piyo") #No line break at the end

python3


print("piyo", file=f) #Newline at the end
f.write("hoge") #No line break at the end
f.write("piyo\n") #Another way to add a newline at the end

Python cannot be written as f.print (abbreviation). print (abbreviation, file = f) was very surprising.

Uncategorized

Conditional operation

ruby


cond=true
val = cond ? "iftrue" : "iffalse"

python3


cond=True
val = "iftrue" if cond else "iffalse"

The conditional operation of python seems to be completely unfamiliar so far.

combination

ruby


[1,2,3].combination(2).to_a #=> [[1, 2], [1, 3], [2, 3]]

python3


import itertools
list(itertools.combinations([1,2,3],2)) #=> [(1, 2), (1, 3), (2, 3)]

python is plural. The point is that it becomes a tuple. There is also permutations.

Thread

ruby


Array.new(4){ |ix| Thread.new{ print ix } }.each(&:join) #=>2103

python3


import threading
ts=[threading.Thread(target=(lambda x=x:print(x))) for x in range(4)]
for t in ts:
   t.start()
for t in ts:
   t.join()

The block of ~~ ruby uses the reference of the value when capturing the variable, so if you write it normally (it is an individual impression), it will work. ~~


2018/3/17 Correction
I think ruby works because a variable called ix is confined in scope and generated every time.
/ 2018/3/17 Correction

For python, the default argument is suspicious, but if you use lambda, it will not work unless you do this or double it. The reason is that python's lambda captures variable references. (Isn't it right?) If this is unpleasant, you can specify the method in target without using lambda.

uuid

ruby


require 'securerandom'
SecureRandom.uuid #=> => "72568c47-e6e0-4f21-a8b5-dad3d72831b2"

python3


import uuid
str(uuid.uuid4()) #=> '9414a2d6-b954-4519-bf88-47828d6d2577'

You can create secure random numbers with a module called secrets, but since python 3.6. Moreover, there seems to be no I / F that creates a uuid.

The uuids for python are ʻuuid1 () , ʻuuid3 (), ʻuuid4 () , ʻuuid5 (). ʻUuid4 ()seems to correspond to ruby'sSecureRandom.uuid`.

String join

It's not a thread join, but a comma that connects the elements of an array.

ruby


[1,"hoge",2.34].join(",") #=> "1,hoge,2.34"

python3


",".join([str(x) for x in [ 1, "hoge", 2.34 ] ] ) #=> '1,hoge,2.34'

When ruby joins, it becomes a string without permission, but python can only join a string. I knew that the receiver was the other way around, but I didn't know that it wouldn't convert it to a string.

String split

ruby


"a,b,c".split(",") # => ["a", "b", "c"]
"a-b+c".split(/\W/) # => ["a", "b", "c"]

python3


import re
"a,b,c".split(",") #=> ["a", "b", "c"]
re.split(r"\W", "a+b-c") #=> ["a", "b", "c"]
re.compile( r"\W" ).split( "a+b-c" ) #=> ["a", "b", "c"]

It is necessary to change the name depending on whether it is a regular expression or not.

It's a pity that you can't write " a, b, c ".split (re.compile (r" \ W ")).

Finally

Will be added. There is a better way to write it! Call for opinions.

Recommended Posts

Note that writing like this with ruby is writing like this with python
[Note] Operate MongoDB with Python
Zundokokiyoshi with python / ruby / Lua
Note that it supports Python 3
Treat the Interface class like that with Python type annotations
This and that for using Step Functions with CDK + Python
[Python] What is a with statement?
Python Note: About comparison using is
Scraping with Node, Ruby and Python
Dynamic proxy with python, ruby, PHP
(Note) Be careful with python argparse
[Note] Hello world output with python
This and that of python properties
Reading and writing NetCDF with Python
Reading and writing CSV with Python
With PEP8 and PEP257, Python coding that is not embarrassing to show to people!
Note that Python dict returns default value if there is no key
Note that admin.py is not reflected immediately when running Django with WSGIDaemonProcess
python note: when easy_install is not available
[Python] A program that creates stairs with #
[Note] Get data from PostgreSQL with Python
Realize PHP / Python generator with Golang / Ruby
Note when creating an environment with python
[Personal note] Web page scraping with python3
Reading and writing JSON files with Python
Trying to handle SQLite3 with Python [Note]
Note that Python decorators should have wraps
Visualize point P that works with Python
Try calling Python from Ruby with thrift
Encrypt with Ruby (Rails) and decrypt with Python
A typed world that begins with Python
Easy web scraping with Python and Ruby
Try something like Python for-else in Ruby
PNG saving is slow with Python imageio.imwrite
#I tried something like Vlookup with Python # 2
About February 02, 2020 * This is a Python article.
When writing tests with python unittests, use doCleanups for setUps that can fail
Are Php / Ruby / Python that only runs when the file is called directly
Note: Python
Boto3 (manipulate AWS resources with Python library) API that is often used privately
Python note
Grammar summary that is often forgotten with matplotlib
How to enjoy programming with Minecraft (Ruby, Python)
Create an app that guesses students with python
[Note] Export the html of the site with python.
Python log is not output with docker-compose up
[Web development with Python] query is also redirect
Create a page that loads infinitely with python
[Note] Create a one-line timezone class with python
I tried using mecab with python2.7, ruby2.3, php7
Note for formatting numbers with python format function
This is the only basic review of Python ~ 1 ~
This is the only basic review of Python ~ 2 ~
Note that Python list comprehensions are always confusing
What are you comparing with Python is and ==?
This is the only basic review of Python ~ 3 ~
Reading and writing fits files with Python (memo)
This and that useful when used with nohup
One-liner that outputs 10000 digits of pi with Python
Sample program that outputs syslog with Python logging
Homebrew Vim doesn't start with Python 3.8 error Note