LoginSignup
2
4

More than 3 years have passed since last update.

【python入門】忙しいC++プログラマのためのPython高速入門講座

Last updated at Posted at 2020-05-24

概要

C++は使えるけどpythonがわからないという人が素早く機械学習ができる最低限のプログラミング記法を身につけるためのポイントをまとめました。これを知っていれば最低限の機能は使えると思います。

Pythonのメリット

ライブラリが充実しているのでC++で書くと複雑なコードも簡単に書けます。web連携が比較的簡単。
ネットに載っている情報が多い。

Pythonの使いみち(例)

以下は全てライブラリが存在します。ライブラリを使いこなすことはすなわちpythonを使いこなすことです。
・機械学習
・Webスクレイピング
・エクセル操作
・データ前処理
・ビジュアライズ

検証環境

python 3.8.2
Ubuntu 18.04

環境構築

linuxの場合は標準でpython3が入っているので環境構築の必要がありません。
Anacondaで動かしたい場合にはこちらを参考に導入してください。
Anacondaの説明はこちら
Anacondaを使うと仮想環境を簡単に作ることができます。パッケージをたくさんインストールするpythonにおいては、環境を変えたいことが多くなるので、本腰を入れて使いたいならAnacondaは必須かもしれません。

おすすめの開発環境

IDE
・PyCharm
・Spyder
エディタ
・Atom
・VS code

C++とPythonの違い一覧

C++ Python
変数型 あり なし
変数の代入 コピー ポインタ
関数の区切り {}中括弧 :とインデント
算術演算子 C++のものに加えて**べき乗を追加
論理演算子 &&,ll,! and,or,not
コードの区切り ; 改行
ポインタ 明確 不明確
コメントアウト // #
外部ライブラリのインポート #include import
コンパイル 必要 不要
main関数 あり なし
行列計算(標準) 不可能 numpyライブラリで可能

変数型の違い

pythonは動的型付け言語のため、C++に当たり前のようにある変数型が存在しません。そのため、変数はそのまま変数名のみで定義します。代入した値によって型が決定します。

a=1234 #整数型
b=12.345 #浮動小数点型
c="hello world" #文字列型
d=[1,2,3,4] #リスト型

ポインタ

pythonには明示的なポインタが存在しません。その代わり、変数が値の保持とポインタの両方の役割を兼ねているので、変数への代入がコピーではなく参照を渡しています。
代入先の値を変更すると代入元の変数の値も変わるので扱いの違いに注意してください。(リストの場合)以下参考
https://qiita.com/maruman029/items/21ad04e326bb4fb6f71a

1コードの範囲

C++の場合は区切り文字である;をつけなければどれだけ改行しても1コードの認識ですが、pythonの場合は改行が明確な区切りになります。

インデント

pythonはインデントがスコープの範囲を示しています。そのため、一文字でもインデントがずれていると同じ範囲のコードとして認識されません。とてもインデントに厳しい言語なので、エディタのインデント整形機能を使わないとコーディングが厳しいかもしれません。例えば、以下のコードはインデンテーションエラーになります。ループの中でインデントがずれてバグが出ることがしばしばあるので気をつけましょう。

a=1234 
b=12.345 
 c="hello world" #同じ範囲でない
d=[1,2,3,4] 

グローバル変数

C++のグローバル変数は関数からそのままアクセスできますが、pythonの場合は関数内でglobal 変数名とローカル内で宣言しないと代入はできません。

a = 123


def Global():
    global a
    a = 456
    print("global variable:", a)


Global()

書き方の違い

見やすくするために一部main関数を省略しています。

標準出力

pythonは自動改行なので\nは要りません。

c.c
int a=123;
printf("%d\n",a);
python.py
a=123
print(a)

外部ライブラリのインポート

c++.cpp
#include "hogohoge.h"
python.py
import hogehoge 

配列

pythonでは「リスト」と呼びます。pythonの配列はメモリ領域が動的に確保されているので、後から要素を追加することができます。要素を追加する場合はappend()を使います。C++のようにa[3] = 4で代入するとエラーになるので気をつけましょう。

c++.cpp
int a[4]={1,2,3,};
int b = a[2];
printf("%d\n", b);

a[3] = 4;
printf("%d\n", a);
python.py
a=[1,2,3]
b=a[2]
print(b)

a.append(4)
print(a)

pythonのコードを見てみると、a.append(4)があります。これはリストメソッドと言って、リストを操作するときに使う関数です。pythonでは変数や外部ライブラリを一種のオブジェクトとして扱い、.メソッドでpythonに用意されているメソッドにアクセスできます。他にも途中に挿入するメソッドなどいろいろ存在するのでこちらが参考になると思います。

不可変配列

後から値を変更することができない配列です。c++ではconstで宣言しますが、pytonの場合はタプルと言ってリストと別の書き方をします。

tupl.cpp
const int a[4] = {1, 2, 3, 4};
b = a[2];
printf("%d", b);
tupl.py
a = (1, 2, 3, 4)
b = a[2]#要素を取得
print(b)

変数のラベル付け

pythonには辞書という機能があります。キーと値の組み合わせでデータを格納できる配列のようなものです。呼び出すときはキーを指定することで呼び出すことができます。そのため可読性が上がります。c++のenumと似たようなものとイメージしてももらうとわかりやすいかもしれません。

python.py
lang={"c":1,"python":2,"ruby":3}#辞書の作成
print(lang["python"])

lang["ruby"]=4#要素の入れ替え
print(lang["ruby"])

lang["java"]=3 #要素の追加
print(lang)

if文

pythonにはc++のように{}などの区切り文字がありません。そのため、if hogehoge:の次の行を1タブ分開けることによって※インデントを変え、if文の処理であることを明示します。pirntを左端に持ってくるとif文と同じインデントになるので、ifのそとで実行される処理になります。ネストする際もまた、インデントをずらします。
※インデントはタブかスペース4つ開けるかどちらかで統一しましょう。混ぜることは禁止されています。万が一混ざってしまい、どうにもならなくなったときはエディタの修正機能を使うことを勧めます。VS codeにはどちらかに統一する機能があります。

c++.cpp
int a = 7;
int b = 12;
if (a <= 10 && b <= 10)
{
    printf("aもbも10以下");
}
else if (a % 2 == 0)
{
    printf("aは偶数");
}
else
{
    printf("条件に適合しません")
}
python.py
a = 7
b = 12
if a <= 10 and b <= 10:
    print("aもbも10以下")
elif a % 2 == 0:
    print("aは偶数")
else:
    print("条件に適合しません")

for文

c++の場合は、配列の中身をひとつひとつ取り出す場合に配列の要素数を指定してループしなければできませんが、
pythonの場合はリストを投げるだけで全要素をひとつずつ取り出してくれます。

for.cpp
int ls[3] = {1, 2, 5};
for (int i = 0; i < sizeof ls / sizeof ls[0]; i++)
{
    printf("%d\n", ls[i]);
}

for (int i = 0; i < 3; i++)
{
    printf("%d\n", i);
}
for.py
ls = [1, 2, 5]
for i in ls:
    print(i)

for i in range(3):
    print(i)

1
2
5
0
1
2

while文

while.cpp
int a = 0;
while(a < 3)
{
    printf("%d", a);
    a += 1;
}
while.py
a = 0
while a < 3:
    print(a)
    a += 1

0
1
2

関数

可変長引数を受け取るときは仮引数の前に*を付けます。
リストやタプルの内容を引数に展開して引き渡すときは実引数の前に*をつけます。

function.cpp
int Add(a, b)
{
    c = a + b;
    return c;
}

int Add3(int *c)
{
    int d = 0;
    d = c[0] + c[1] + c[2];
    return d;
}

int main()
{
    printf("%d\n", Add(1, 2));

    const int e[3] = {1, 2, 3};
    printf("%d\n", Add3(e));
}
function.py
def Add(a, b):
    c = a + b
    return c

def Add3(*c):  # 可変超引数として引数をまとめて受け取る
    d = c[0] + c[1] + c[2]
    return d


def main():
    print(Add(1, 2))
    print(Add3(1, 2, 3))
    e = (4, 5)
    print(Add(*e))  # リストやタプルを引数展開して渡すことも可
    return


if __name__ == "__main__":
    main()

クラス

クラスの定義

classdefine.cpp
class Hoge
{
public:
    int a;
    Hoge(int a)
    {
        this->a = a;
    }
    void add(int b)
    {
        printf("%d\n", a + b);
    }
    void mutipl(int b)
    {
        printf("%d\n", a * b);
    }
}
classdefine.py
class Hoge:
    def __init__(self, a):
        self.a = a

    def add(self, b):
        print(self.a + b)

    def mutipl(self, b):
        print(self.a * b)

c++でコンストラクタをクラスと同じ名前にしますが、pythonの「クラス」ではコンストラクタをdef __init__(self, a):で表し、クラス内の変数をコンストラクタ内でself.aのように宣言します。定義自体はどこからでもできます。メンバ関数の引数にクラス自身の参照である「self」を渡して「self」経由でインスタンス変数にアクセスします。必ず引数にselfを書きましょう。

クラスの操作

classcntrol.cpp
Hoge hoge(3);
hoge.add(4);
hoge.mutipl(4);
classcontrol.py
hoge = Hoge(3)
hoge.add(4)
hoge.mutipl(4)

クラスの継承

Inheritance.cpp
class Fuga : public Hoge
{
public:
    void subtract(int b)
    {
        printf("%d\n", a - b);
    }
    void divide(int b)
    {
        printf("%d\n", a / b);
    }
}

Fuga fuga(3);
fuga.add(4);
fuga.mutipl(4);
fuga.subtract(4);
fuga.divide(4);
Inheritance.py
class Fuga(Hoge): #Hogeを継承
    def subtract(self, b):
        print(self.a - b)

    def divide(self, b):
        print(self.a/b)

fuga = Fuga(3)
fuga.add(4)
fuga.mutipl(4)
fuga.subtract(4)
fuga.divide(4)

Pythonの主力ライブラリ

Numpy(行列演算ライブラリ)

これを使うことで行列演算が非常に簡単にできます。機械学習では必須です。
こちらの方が詳しく使い方を書いてあるので参考にしてください。

Matplotlib(グラフ描画ライブラリ)

書き方はこちらの記事を参考にしてください。

補足

importモジュールの置き換え

pythonでは、外部ライブラリはオブジェクトとして扱われますが、長い名前を書くのが面倒なのでasで置き換えることもできます。

import numpy as np

モジュールのインストール

pip3 install module_name

Pythonスクリプトの実行

python3 file_name

anaconda

python file_name

標準ライブラリ

pythonではファイル操作がかなり楽です。
https://qiita.com/hiroyuki_mrp/items/8bbd9ab6c16601e87a9c

オブジェクト指定インポート

最後に

まだまだpythonのほんの一部なので、気になった機能はあるかどうか調べてみるとよいです。

参考

我妻 幸長 (著) "はじめてのディープラーニング Pythonで学ぶニューラルネットワークとバックプロパゲーション"

2
4
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
4