Comparing the basic grammar of Python and Go in an easy-to-understand manner

This article is an article on Tuesday, December 24th of DeNA Advent Calendar 2019.

Introduction

I usually use Perl mainly, but I summarized it for the purpose of learning Go and reviewing Python. The grammar of Python is very simple, so I thought it would be quick to learn Go by the difference. I intend to write as much as possible, but I think there are various shortages. Please note.

comment

First of all, how to write a comment. Python doesn't originally have the ability to comment out multiple lines, but putting a string in your program has no effect, so you can use it to write multi-line comments. Also, multi-line comments can be left as a documentation string.

Python


#1-line comment

'''
Multi-line comment
'''
"""
Multi-line comment
"""

def func():
   """
Program commentary, etc.
   """
   
help(func)
print(func.__doc__)

Go


//1-line comment

/*
Multi-line comment
*/

Variable definition

Python is a dynamically typed language, so you don't need to declare the type of a variable.

Python


n = 10
name = "hoge"

#Define all together
x, y, z = 1, 2, 3
a = b = c = 1

In the case of Go, you should first pay attention to the first character of the variable name.

This also applies to constants and functions. Go is a statically typed language, but there are explicit and implicit definitions.

Explicit definition

Define it as var [variable name] [variable type].

Go


var n int
n = 1

//Define all together
var x, y, z int
x, y, z = 1, 2, 3

var (
    x, y int
    name string
)
x, y, name = 1, 2, "hoge"

//Declare the type and assign the value at the same time
var n int = 1
Implicit definition

Define it as [variable name]: = [value] or var [variable name] = [value]. Assigning a value implicitly infers the type of the variable.

Go


n := 1

//Type can be omitted even in the definition using var
var n = 1

//Define all together
x, y, name := 1, 2, "hoge"

var (
    x = 1
    y = 2
    name = "hoge"
)

constant

Python has no keywords for defining constants. By convention, only uppercase letters and underscores represent constants.

Python


PI = 3.14
MAX_NUM = 100

Go uses const to define constants. You can use the identifier ʻiota` to generate a sequence of integers. Attempting to change the value of a constant will result in an error.

Go


const Pi = 3.14
const MaxNum = 100

// ()Define collectively in
const (
    Pi = 3.14
    MaxNum = 100
)

const (
    X = iota  // 0
    Y         // 1
    Z         // 2
)

//When specifying the start number
const (
    X = iota + 10  // 10
    Y              // 11
    Z              // 12
)

Array

Python arrays (lists) are very simple to write. The following is the basic usage.

Python


#Definition
numbers = [1, 2, 3]

#Add element
numbers.append(6)
numbers.insert(3, 5)  # numbers: [1, 2, 3, 5, 6]

#Element count
len(numbers)

#Delete element
numbers.remove(3)  # numbers: [1, 2, 5, 6]
numbers.pop(1)  # numbers: [1, 5, 6]
del numbers[0]  # numbers: [5, 6]

#Combine lists
numbers += [3, 4]  # numbers: [5, 6, 3, 4]
numbers.extend([1, 2])  # numbers: [5, 6, 3, 4, 1, 2]

#Search for elements
print(6 in numbers)  # True
print(numbers.index(6))  # 1

#Sort the list
numbers.sort()  # numbers: [1, 2, 3, 4, 5, 6]
numbers.sort(reverse=True)  # numbers: [6, 5, 4, 3, 2, 1]

Go's array type cannot be scaled up or down. Data structures like Python's lists are equivalent to slices in Go. The ʻappendfunction is often used for slicing operations. For **...`, see [Variadic function arguments](#variadic arguments). ** **

Go


//Array cannot be resized
array := [3]int{1, 2, 3}
fmt.Println(array[0])  // 1
fmt.Println(array[1:3])  // [2 3]

//slice
n1 := []int{}  // n1: []
n2 := make([]int, 0)  // n2: []
numbers := []int{1, 2, 3}

//Add element
numbers = append(numbers, 6)  // numbers: [1 2 3 6]
numbers = append(numbers[0:3], append([]int{5}, numbers[3:]...)...)  // numbers: [1 2 3 5 6]

//Element count
len(numbers)

//Delete element
numbers = append(numbers[0:2], numbers[3:]...)  // numbers: [1 2 5 6]
numbers = numbers[2:]  // numbers: [5 6]

//Combine arrays
numbers = append(numbers, []int{3, 4, 1, 2}...)  // numbers: [5 6 3 4 1 2]

//Search for elements
//There is no equivalent to the Python index, so write it yourself
fmt.Println(IndexOf(numbers, 6))  // 1

func IndexOf(s []int, n int) int { 
    for i, v := range s { 
        if n == v { 
            return i 
        } 
    } 
    return -1
}

//Sort array
//use sort package
sort.Ints(numbers)
fmt.Println(numbers)  // [1 2 3 4 5 6]
sort.Sort(sort.Reverse(sort.IntSlice(numbers)))
fmt.Println(numbers)  // [6 5 4 3 2 1]

Associative array

Python uses a data structure called a dictionary.

Python


#Definition
dic = {'hoge': 1, 'fuga': 2, 'piyo': 3}
list1 = [('hoge', 1), ('fuga', 2), ('piyo', 3)]
dic2 = dict(list1)  #Same as dic value
dic['hoge']
dic.get('hoge')

#Add and remove elements
dic['foo'] = 4
dic.setdefault('bar', 5)
dic.pop('hoge')  # {'fuga': 2, 'piyo': 3, 'foo': 4, 'bar': 5}
del dic['fuga'], dic['piyo']  # {'foo': 4, 'bar': 5}

#Element count
len(dic)

#Confirmation of key existence
'foo' in dic

#Retrieving keys and values
list(dic.keys())  # ['foo', 'bar']
list(dic.values())  # [4, 5]
for k, v in dic.items():
    print(k, v)

Go's map is equivalent to Python's dictionary. It is defined in the following format. map [key type] element type

Go


//Definition
dic := map[string]int{"hoge": 1, "fuga": 2, "piyo": 3}
dic2 := make(map[string]int)
fmt.Println(dic)  // map[fuga:2 hoge:1 piyo:3]
fmt.Println(dic2)  // map[]

//Add and remove elements
dic["foo"] = 4
delete(dic, "hoge")
fmt.Println(dic)  // map[foo:4 fuga:2 piyo:3]

//Element count
len(dic)

//Confirmation of key existence
_, exist := dic["foo"]
fmt.Println(exist)  // true
if value, exist := dic["foo"]; exist {
    fmt.Println(value)  // 4
}

//Retrieving keys and values
for k, v := range dic {
    fmt.Println(k, v)
}

Conditional branch

Python does not have a switch statement. Use ʻif ... elif ... else` instead. There is also a way of writing called a conditional expression (ternary operator).

6.12. Conditional Expressions https://docs.python.org/ja/3/reference/expressions.html#conditional-expressions

Logical operators use ʻand, ʻor, not.

Python


x, y = 1, 2
if x > y:
    print('x > y')
elif x < y:
    print('x < y')
else:
    print('x == y')

n = 10
#Conditional expression
result = "positive" if n > 0 else "negative or zero"

There are two types of conditional branches in Go, if and switch, and you can define valid variables only in that block by writing if with a simple statement. There is no ternary operator, but you can write it like that with map. Logical operators&&,||,!Use the.

Go


x, y := 1, 2
if x > y {
    fmt.Println("x > y")
} else if x < y {
    fmt.Println("x < y")
} else {
    fmt.Println("x == y")
}

#If with a simple sentence
if x, y := 1, 2; x > y {
    fmt.Println("x > y")
} else if x < y {
    fmt.Println("x < y")
} else {
    fmt.Println("x == y")
}

#switch statement
x, y := 1, 2;
switch {
case x > y:
    fmt.Println("x > y")
case x < y:
    fmt.Println("x < y")
default:
    fmt.Println("x == y")
}

n := 10
#How to write like a ternary operator
result := map[bool]string{true: "positive", false: "negative"}[n > 0]

loop

Python loop processing uses for and while.

Python


sum = 0
for num in range(1, 11):
    sum += num

num, sum = 1, 0
while num <= 10:
    sum += num
    num += 1

#infinite loop
num, sum = 1, 0
while True:
    sum += num
    num += 1
    if num > 10:
        break

There is only a for loop in Go, but you can also control it like while.

Go


sum := 0
for num := 0 ; num <= 10 ; num++ {
    sum += num
}

// while
num, sum := 1, 0
for num <= 10 {
    sum += num
    num++
}

//infinite loop
num, sum := 1, 0
for {
    sum += num
    num++
    if num > 10 {
        break
    }
}

function

Python functions are defined with def. The function definition must be written before the function call is executed. There are the following usages.

Python


def greet(name="World"):
    print("Hello, " + name)

greet()
greet("Alice")
greet(name="Alice")

#Variadic variable
def greet(*names):
    for name in names:
        print("Hello, " + name)

greet("Alice", "Bob", "Carol")

#Multiple return values
def cal(a, b):
    add = a + b
    mul = a * b
    return add, mul

add, mul = cal(10, 5)

Go functions are defined with func. func [function name]([argument definition]) [return type] {[function body]} There are no default or keyword arguments, but they have the following characteristics:

Variadic argument

Variadic arguments for functions are defined as [argument name] ... [argument type]. And if you pass a slice as a variadic argument, you need to add ... after the variable to expand the slice.

Go


func main() {
    add, mul := cal(10, 5)
    fmt.Println(add, mul) // 15 50
    add, mul = calc(10, 5)
    fmt.Println(add, mul) // 15 50

    greet("Alice", "Bob", "Carol")
    names := []string{"Alice", "Bob", "Carol"}
    greet(names...)  //Pass a slice as a variadic argument

    testDefer() // BDCA
}

//Uninflected word
func cal(a int, b int) (int, int) {
    add := a + b
    mul := a * b
    return add, mul
}

//Named return value
//If the argument types are the same, you can write them all together
func calc(a, b int) (add int, mul int) {
    add = a + b
    mul = a * b
    return 
}

//Functions with no return value
//Variadic argument
func greet(names ...string) {
    for _, name := range names {
        fmt.Println("Hello,", name)
    }
}

//defer deferred execution
func testDefer() {
    defer fmt.Print("A")
    fmt.Print("B")
    defer fmt.Print("C")  //C is output before A
    fmt.Print("D")
}

Exception handling

Python uses the try-except syntax to catch and handle exceptions.

Python


def doDivision(x, y):
    try:
        result = x / y
    except Exception as e:
        result = None
        print("except:" + e.args[0])
    else:  #Execute at normal end
        print("else")
    finally:  #Always run on exit
        print("finally")
    return result

doDivision(10, 2)
# else
# finally
doDivision(10, 0)
# except:test exception
# finally

There is no exception mechanism like try-except in Go. Instead, it uses the property of being able to return multiple return values of a function to detect an error by returning whether an error has occurred (ʻerror interface) as part of the return value. The ʻerror interface is defined as follows: https://golang.org/pkg/builtin/#error

Go error interface


type error interface {
    Error() string
}

The following example uses the New function of the ʻerrors package to generate a ʻerror type. You can also use defer to achieve the same behavior as Python's finally.

Go


package main
import (
    "fmt"
    "errors"
)

func main() {
    _, err := doDivision(10, 2)
    if (err != nil) {
        //Error handling
    }
    // defer
    
    _, err = doDivision(10, 0)
    if (err != nil) {
        //Error handling
    }
    // error
    // defer
}

func doDivision(i, j int) (result int, err error) {
    defer fmt.Println("defer")  //Always run on exit

    if j == 0 {
        fmt.Println("error")
        err = errors.New("Divided by Zero")
        return
    }
    result = i / j
    return
}

In addition, Go also has an error handling mechanism called panic / recover, but I will omit it here.

class

The following is an example of a simple Python class.

Python


class Player:
    def __init__(self, id, name):
        self.id = id
        self.name = name
        self.__hp = 100

    @property
    def hp(self):
        return self.__hp

    def consume_hp(self, num):
        self.__hp -= num
        
player = Player(10001, "Alice")
print(player.hp) # 100
player.consume_hp(10)
print(player.hp) # 90

Go doesn't have a syntax equivalent to class in Python, but it uses a struct that handles related variables together in a similar role. You can define methods for the structure. Unlike functions, methods require a receiver type and its variable name. The following example defines a method called consumeHp for a pointer type called * Player.

Go


//Player type structure
type Player struct{
    ID int
    Name string
    Hp int
}

//constructor
func newPlayer(id int, name string) Player {
    return Player{ID: id, Name: name, Hp: 100}
}

// *Player type method
func (p *Player) consumeHp(num int) {
    p.Hp -= num
}

func main() {
    p := newPlayer(10001, "Alice")
    fmt.Println(p.Hp) // 100
    p.consumeHp(10)
    fmt.Println(p.Hp) // 90
}

Multithread

At the end, I will write a little about multithreading. Below is a simple example of using the threading module to spawn a thread and pass data in a queue.

Python


import threading
import time
from queue import Queue

def worker(a, b, q):
    time.sleep(1)
    result = a + b
    q.put(result)  #Put an element in the queue
    print("result:", result)

q = Queue()
thread = threading.Thread(target=worker, args=(2, 3, q))
thread.start()
thread.join()

print("main thread")
result = q.get()  #Remove elements from the queue
q.task_done()
print("received:", result)  # received: 5

Let's do the same with Go. In Go, a lightweight thread, goroutine, is implemented to run in parallel. Writing go f (x) starts a new goroutine and executes the function. It uses a data structure called a channel to pass data between goroutines. The channel type name is written as chan [data type].

Go


package main

import (
    "fmt"
    "time"
)

func newThread(a, b int, ch chan int) {
    time.Sleep(1000)
    result := a + b
    ch <- result  //Send data to channel
    fmt.Println("result:", result)
}

func main() {
    ch := make(chan int)  //Generate a channel
    go newThread(2, 3, ch)  //Run newThread in a new goroutine

    fmt.Println("main thread")
    result := <-ch  //Receive data from channel
    close(ch)
    fmt.Println("received:", result)  // received: 5
}

Finally

I've seen the Go language grammar in comparison to Python. Although Go is a statically typed language, it is also as easy to write as a dynamically typed language such as Python. As Go is said to be influenced by various languages, I think that anyone who understands C can immediately understand pointers and structures in Go. I couldn't elaborate on goroutine and channel, which are important for concurrency, but I'd like to write them again.

Recommended Posts

Comparing the basic grammar of Python and Go in an easy-to-understand manner
[Python] I tried to summarize the set type (set) in an easy-to-understand manner.
Open an Excel file in Python and color the map of Japan
Ruby expert learned the basic grammar of Go language
Python installation and basic grammar
Python (Python 3.7.7) installation and basic grammar
I wrote the basic grammar of Python with Jupyter Lab
[Tips] Problems and solutions in the development of python + kivy
Java and Python basic grammar comparison
[For beginners] I want to explain the number of learning times in an easy-to-understand manner.
About the basic type of Go
Basic grammar of Python3 system (dictionary)
Count the number of Thai and Arabic characters well in Python
Check if the configuration file is read in an easy-to-understand manner
New Python grammar and features not mentioned in the introductory book
Get the title and delivery date of Yahoo! News in Python
The story of an error in PyOCR
The story of making Python an exe
The result of installing python in Anaconda
The basics of running NoxPlayer in Python
[Python] I personally summarized the basic grammar.
Basic grammar of Python3 system (character string)
Basic grammar of Python3 series (list, tuple)
In search of the fastest FizzBuzz in Python
Python Basic Course (at the end of 15)
Basic grammar of Python3 system (included notation)
Project Euler # 1 "Multiples of 3 and 5" in Python
Change the saturation and brightness of color specifications like # ff000 in python 2.5
An example of the answer to the reference question of the study session. In python.
Output the number of CPU cores in Python
plot the coordinates of the processing (python) list and specify the number of times in draw ()
[Python] Sort the list of pathlib.Path in natural sort
Summary of the differences between PHP and Python
I compared the speed of go language web framework echo and python web framework flask
You will be an engineer in 100 days --Day 33 --Python --Basics of the Python language 8
You will be an engineer in 100 days --Day 26 --Python --Basics of the Python language 3
I compared the speed of regular expressions in Ruby, Python, and Perl (2013 version)
Get the caller of a function in Python
Match the distribution of each group in Python
The answer of "1/2" is different between python2 and 3
Divides the character string by the specified number of characters. In Ruby and Python.
Implemented memoization recursion and exploration in Python and Go
Specifying the range of ruby and python arrays
Make a copy of the list in Python
About the difference between "==" and "is" in python
Install the python package in an offline environment
Find the divisor of the value entered in python
Compare the speed of Python append and map
Set an upper limit on the number of recursive function iterations in Python
This is the only basic review of Python ~ 1 ~
This is the only basic review of Python ~ 2 ~
What you want to memorize with the basic "string manipulation" grammar of python
You will be an engineer in 100 days --Day 32 --Python --Basics of the Python language 7
Find the solution of the nth-order equation in python
The story of reading HSPICE data in Python
Python3 basic grammar
[Note] About the role of underscore "_" in Python
About the behavior of Model.get_or_create () of peewee in Python
Solving the equation of motion in Python (odeint)
Y / n processing in bash, python and Go
Output in the form of a python array