====== Python ====== ===== 概要 ===== * スクリプト言語の一つ * 関数や if 文などの {} をインデントで代用するため、可読性が高い * 2.x と 3.x で完全な互換性はない * Linux の主要ディストリビューションには、デフォルトでインストールされている * スクリプト言語の中では、高速に処理できるらしい * 科学計算などのライブラリが充実している * 対話的にプログラムができる (命令文のテストなどちょっと試したい時に最適) * その他、便利な特徴: [[http://webtech-walker.com/archive/2010/10/13191417.html | Python初心者によるPythonのいいところ、はまりどころのまとめ - Webtech Walker]] ===== インストール ===== * [[Python/anyenv を用いた Python のインストール方法]] ===== 構文 ===== ==== ファイルの先頭 ==== * Python 2\\ #!/usr/bin/env python # -*- coding: utf-8 -*- * Python 3\\ #!/usr/bin/env python3 # -*- coding: utf-8 -*- * 1 行目は実行するプログラムを指定するシバン行 * ''/usr/bin/env ...'' の代わりに直接 Python のパスを指定しても良い * env は引数のプログラミング言語のパスを自動で拾ってきてくれる * 環境が違っても env があれば、対応できるプログラムになる * 2行目に文字コードを指定する (日本語などが含まれる場合、指定しないとエラーになる) ==== 変数 ==== * 定義\\ variable_name = value * Python では変数の型が動的に割り当てられるため、型定義は不要 ==== 配列 (リスト) ==== * 定義\\ array_name = [value1, value2, ...] * リストは角括弧で定義 * 呼び出し\\ print(array_name[index]) * 配列名の後に角括弧で、0 から始まる配列番号を入れると個別に値を取り出すことができる * index が負数だと、後ろからの番号になる (-1: 末尾の配列番号、-2: 末尾から1つ前の配列番号、...) * スライスによる呼び出し\\ print(array_name[start:end]) * 連続する要素をリストとして呼び出すこともできる * start 及び end は片方、省略でき、start を省略すると「先頭から」、end を省略すると「末尾まで」を指定したことになる * start と end の数字は、要素の間の番号だと考えると良い\\ 要素名 : val1 val2 val3 val4 val5 開始/終了番号: 0 1 2 3 4 5 * 例: 1:3 と指定した場合は上記の場合だと、val2 から val3 が得られる * 参考サイト: [[http://www.kabipan.com/computer/python/ | www.kabipan.com/computer/python/]] * 値の追加\\ array_name.append(value) * append を使って、末尾に挿入する * 参考サイト: [[http://d.hatena.ne.jp/yumimue/20071205/1196839438 | リスト - 作成、取り出し、置換、追加、検索、削除、要素数 - ひきメモ]] ==== 連想配列 (ハッシュ、ディクショナリ) ==== * Python でハッシュ (キーと値のペアで情報を持つ配列) をディクショナリと呼ぶ * 定義\\ dic_name = {key1:value1, key2:value2, ...} * ''dic_name'' にディクショナリ名 * ''key1'', ''key2'' にキー名 * ''value1'', ''value2'' に値 * 波括弧で定義 * 呼び出し\\ dic_name[key] * 角括弧で呼び出す * キーをリストで取得する\\ dic_name.key() * ''dic_name'' にディクショナリ名 * for 文を使って hoge というディクショナリの値を取得する場合\\ for i in hoge.keys(): print(hoge[i]) * 値をリストで取得する\\ dic_name.values() * 参考サイト: [[http://www.pythonweb.jp/tutorial/dictionary/ | 辞書(ディクショナリ) - Python入門]] ==== 関数の定義 ==== def function_name(arg1, arg2, ...): ... * def で始め、''function_name'' に関数名を入れる * 引数は関数名の後の () に入れた変数名に、関数の呼び出しで入れた引数が代入される ==== 関数の呼び出し ==== function_name(arg1, arg2, ...) * 関数名 ''function_name'' をそのまま入れるだけ * 引数 ''arg1'', ''arg2'' が引数として、関数に与えられる ==== 無名関数 (ラムダ(lambda)式) ==== * 即席関数 (関数として定義するでもないが、別の関数の引数に関数が必要な場合に便利) * 構文\\ lambda arg:return * ''arg'' は引数を指定 (複数指定する場合は、「,」で区切る) * ''return'' に返り値を指定 * 例: 2倍の値を返す関数\\ >>>myfunc = lambda x: x*2 >>> myfunc(3) 6 * 例: 奇数に対し、True を返す関数\\ myfunc = lambda n: n % 2 == 1 >>> myfunc(3) True >>> myfunc(2) False * 後述する組み込み関数で使える * 参考サイト * [[http://www.lifewithpython.com/2013/01/python-anonymous-function-lambda.html | Pythonの無名関数(lambda)の使い方 - Life with Python]] * [[http://emoson.hateblo.jp/entry/2014/10/14/022053 | lambda式はすごく面白い - 元理系院生の新入社員がPythonとJavaで色々頑張るブログ]] ==== 組み込み関数 ==== * 参考サイト: [[http://python.civic-apps.com/map-reduce-filter/ | map, reduce, filterによるシーケンス操作 | Python Snippets]] === map === * リストの要素、全てに対し指定した関数を実行する (for 文で各要素に処理するのと同じ) * 構文\\ array_result = map(function, array) * ''function'' にリストに対して処理したい関数を指定する * ''array'' に処理したいリストを指定する * 例: リストを浮動小数に変換する\\ result = map(float, hoge) * 返り値は 2.x と 3.x で異なるため、[[#map_filter_zip_関数 | Python 2.x と 3.x の違い の map,filter,zip 関数]]を参照されたし === filter === * 条件に合致する値を抽出する (perl の grep みたいな関数) * 構文\\ filter(function, array) * ''function'' に条件判断する関数を指定する * ''array'' に処理したいリストを指定する * 例: 奇数のみ抽出する\\ >>> hoge = [1,2,3,4,5] >>> filter(lambda n: n % 2 == 1, hoge) [1, 3, 5] * 返り値は 2.x と 3.x で異なるため、[[#map_filter_zip_関数 | Python 2.x と 3.x の違い の map,filter,zip 関数]]を参照されたし === reduce === * リストを集約する関数 (リストの値を for 分を使って取り出し、最終的に返り値を出す関数) * 合計値を求める関数が reduce で代用できる * 構文\\ reduce(function, array) * ''function'' に集約する関数を指定する * ''array'' に処理したいリストを指定する * 例: 合計を算出する\\ >>> hoge = [1,2,3,4,5] >>> reduce(lambda x,y: x+y, hoge) 15 * 3.x では functools モジュールに取り込まれたので、import してから使う\\ from functools import reduce * 参考サイト: [[http://qiita.com/mriho/items/0cadc16c9c01e652db5e | 【備忘録】Python3でのreduce - Qiita]] ===== よく使う関数 ===== * [[python/print | print]]: 画面上に文字を表示する ===== よく使うモジュール ===== * [[python/argparse | argparse]]: コマンドライン引数を解析するモジュール * [[python/Biopython | Biopython]]: アメリカの国立生物工学情報センターのデータベースにアクセスできる API モジュール * [[python/easygui]]: 簡単なダイアログを表示するモジュール (qt 版も含む) * [[python/itertools | itertools]]: イテレータ作成モジュール (順列や組み合わせ、直積、階乗で使える) * [[python/joblib]]: 並列処理モジュール (別途導入が必要) * [[python/math]]: 数学モジュール * [[python/matplotlib | Matplotlib]]: グラフを描画するモジュール * [[python/Notify | Notify]]: 通知バルーンモジュール (Linux のデスクトップ環境で通知する際に使う) * [[python/numpy | numpy]]: 数値計算モジュール * [[python/openpyxl]]: xlsx を編集するモジュール * [[python/operator-itemgetter]]: 多次元配列を特定のキーで抽出するモジュール (ソートに使う) * [[python/os | os]]: オペレーティングシステムインターフェースを扱うモジュール (ファイルの移動など) * [[python/pandas | pandas]]: データフレームを扱うモジュール * [[python/parmed | parmed]]: Gromacs や AMBER の構造やトポロジーファイルを扱うモジュール * [[python/re | re]]: 正規表現を扱うモジュール * [[python/scipy]]: 科学技術計算モジュール * [[python/sqlite3 | sqlite3]]: SQLite を扱うモジュール * [[python/subprocess]]: サブプロセスを扱うモジュール (外部コマンドを使うなど) * [[python/sys | sys]]: システムパラメータを扱うモジュール (標準入出力やシグナルなど) * [[python/textwrap]]: 行の長さなどを自動調整するモジュール * [[python/tqdm]]: 進捗表示モジュール (別途導入が必要) ===== 自作モジュール ===== * 自作モジュールの作成手順 (実行する python ファイルを ''main.py''、モジュールファイルを ''module.py'' とする) - 関数やクラスを列挙したモジュールファイル (module.py) を作成 - モジュールファイルがあるディレクトリに ''%%__init__.py%%'' というファイル名の空ファイルを配置する (モジュールファイルがあることを示すファイル) - モジュールパスの追加 * **main.py と同じディレクトリにモジュールがある場合**\\ ./main.py ./module.py * main.py に ''import module'' を追加する (import の後は .py を抜いたファイル名を指定) * **main.py と同じディレクトリにモジュールを含んだディレクトリ (module_dir) がある場合**\\ ./main.py ./module_dir/module.py * main.py に ''import module_dir.module'' を追加する (module_dir と module.py の間はスラッシュではなく、ピリオドで区切る) * main.py に ''from module_dir import module'' を追加する (ディレクトリとモジュールファイルを分ける場合) * **main.py とは別の階層にモジュールを含んだディレクトリがある場合**\\ ./main.py /path/to/module_dir/module.py * 環境変数に追記する場合 - 環境変数 ''PYTHONPATH'' にモジュールディレクトリを追加 (ここでは端末上での表記だが、.bashrc や .zshrc などに記述すると恒久的に利用可)\\ $ export PYTHONPATH=$PYTHONPATH:/path/to/module_dir/ - main.py に ''import module'' を追加する (環境変数に追加したディレクトリから階層になっている場合は ''from'' や ''.'' を使って階層を示す) * スクリプト内部で環境変数を追加する場合 - main.py に以下を追記\\ import sys sys.path.append("/path/to/module_dir") - main.py に ''import module'' を追加する (環境変数に追加したディレクトリから階層になっている場合は ''from'' や ''.'' を使って階層を示す) * 参考サイト: * [[http://otiai10.hatenablog.com/entry/2013/08/13/215034 | Python3のimport・下位/上位階層のモジュールをインポートしたい【import】【Python3】 - DRYな備忘録]] * [[http://www.lifewithpython.com/2014/01/python-add-directories-to-path-to-import-libraries-from.html | Python Tips:ライブラリ読み込み対象ディレクトリを追加したい - Life with Python]] * [[http://samurait.hatenablog.com/entry/__init__.py%E3%81%AE%E5%BD%B9%E5%89%B2 | __init__.pyの役割 - Python, web, Algorithm 技術的なメモ]] * [[http://qiita.com/Accent/items/efb57d66309f6c0ee63d | Pythonで自作モジュールを手軽に使う - Qiita]] ===== Python 3.4 以降のモジュールのリロード ===== * 自作モジュール (''sample'') のリロード - リロード用モジュールの読み込み\\ import importlib - 通常のモジュール読み込み\\ import sample - モジュールのリロード\\ importlib.reload(sample) * ''from'' 付きのモジュールのリロード - リロード用モジュールの読み込み\\ import importlib - 通常のモジュール読み込み\\ from sample import SampleClass - モジュールのリロード\\ import sample importlib.reload(sample) from sample import SampleClass * 参考サイト: [[http://nihaoshijie.hatenadiary.jp/entry/2017/08/28/200626 | Python で class のみ reload - いっきに Python に詳しくなるサイト]] * Python 2.x では ''reload()''、Python 3.3 までは ''imp.reload()'' を使うらしい…。 ===== Python 2.x と 3.x の違い ===== * 2.x 以下のバージョンでは、完全な互換性があったようだが、3.x で一部機能について互換性がなくなった * その違いをメモしてみた ==== Print ==== * [[http://mumeiyamibito.0am.jp/doku.php/python/print#python_2x_と_python3x_の違い | print() 関数]] のページを参照 ==== map / filter / zip 関数 ==== * 2.x はリストで返す\\ >>> array = [1,2,3,4,5] >>> print array [1, 2, 3, 4, 5] >>> print map(float, array) # 値をすべて浮動小数に変換して出力する [1.0, 2.0, 3.0, 4.0, 5.0] * 3.x はイテレータ (オブジェクト) で返す\\ >>> array = [1,2,3,4,5] >>> print(array) [1, 2, 3, 4, 5] >>> print(map(float, array)) # 値をすべて浮動小数に変換して出力する * 2.x のようにリストで返すには list 関数を用いる\\ >>> array = [1,2,3,4,5] >>> print(list(map(float, array))) [1.0, 2.0, 3.0, 4.0, 5.0] * 2.x ではリストを処理する際に一度にのメモリを確保していたが、3.x (イテレータ) では、効率的にメモリを使うことができるらしい (巨大なリストを扱う際の負荷が少なくなる?) * 参考サイト: [[http://qiita.com/croissant1028/items/94c4b7fd360cfcdef0e4 | Python 2 と 3 での高階関数の使い方の比較 - Qiita]] ===== Tips ===== ==== 端末出力文字列に色を付ける ==== * エスケープシーケンスを使う * 色を変える文字の前にエスケープシーケンスを挿入する * ''\033'' (エスケープシーケンス) + ''['' + ''制御コード'' + ''m'' ^ 分類 ^ 制御コード ^ 意味 ^ | 修飾 |0|リセット| |:::|4|太字| |:::|5|点滅(使用環境により使えない場合あり)| |:::|7|反転| | 文字色 |30|黒 (文字色)| |:::|31|赤| |:::|32|緑| |:::|33|黄土色| |:::|34|青| |:::|35|赤紫 (マゼンタ)| |:::|36|水色 (シアン)| |:::|37|灰色 (暗めの白)| |:::|90|暗めの灰色 (明るい黒)| |:::|31|明るい赤| |:::|32|明るい緑 (黄緑)| |:::|33|黄色| |:::|34|明るい青| |:::|35|明るい赤紫 (マゼンタ)| |:::|36|明るい水色 (シアン)| |:::|37|白| | 背景色 |40|黒| |:::|41|赤| |:::|42|緑| |:::|43|黄土色| |:::|44|青| |:::|45|赤紫 (マゼンタ)| |:::|46|水色 (シアン)| |:::|47|白| * 文字色や修飾を変更した場合、''\033[0m'' (リセット) を最後にしないと、次の出力でも同じ文字色 (修飾) で出力される。(リセットは一度で十分) * 複数のコードを使いたい場合 (背景色と下線を使うなど) * 1つのエスケープシーケンス内に複数のコードを '';'' で区切って記述する (例: ''\033[31;1;4;44m'') * エスケープシーケンスを複数記述する (''\033[31m\033[1m\033[4m\033[44m'') * ''termcolor'' モジュールの ''colored()'' 関数を用いる方法もある。 * やっていることは、与えられた文字列に対し、エスケープシーケンスを付加しているだけである。 * [[https://qiita.com/pytry3g/items/f23e3676a1c939f2d69e | とりあえずpythonでtermcolorを使ってみた - Qiita]] * 参考サイト * [[http://atomic.jpn.ph/prog/io/ansiesc.html | プログラム用例 - 入出力 - カラー文字]] * [[http://qiita.com/hidai@github/items/1704bf2926ab8b157a4f | ターミナルで使える色一覧(8色ANSIエスケープシーケンス) - Qiita]] ==== 文字列を 1 文字ずつ区切る ==== * 文字列をリストに変換する。\\ text = "abcdefg" list(text) # -> ['a', 'b', 'c', 'd', 'e', 'f', 'g'] * 参考サイト: [[http://nfnoface.hatenablog.com/entry/2016/10/05/131600 | Pythonで文字列を1文字ずつ分割する - Webプログラムの技術メモ他]] ==== 定義済みのユーザ関数名の一覧を表示する ==== * 関数が定義済みかどうかを調べる時に使う (モジュールなどの外部のプログラムを使う時にどうぞ)。\\ import types print([f.__name__ for f in globals().values() if type(f) == types.FunctionType]) * 参考サイト: [[https://stackoverflow.com/questions/6315496/display-a-list-of-user-defined-functions-in-the-python-idle-session | Display a list of user defined functions in the Python IDLE session - Stack Overflow]] {{tag>プログラミング}}