【Python】個人的逆引きリファレンス
Pythonでの個人的によく書くコードを逆引きリファレンスとしてまとめておこうと思います。(随時更新)
注意:
- Python2.7を対象としてます
- Pythonに詳しいわけではないので変な書き方をしているかもしれません
- 動作確認してません
- リンク
- 言語機能
- イテレータブルオブジェクト(list,dictなど)
- 辞書
- 辞書を作成する : {key:value}
- 空辞書を作成する : {}
- 項目数を取得する : len(dictObj)
- キーが存在するかどうかを取得する : key in dictObj
- キーに対応する値を取得する : dictObj.get( key )
- キーに対応する値を設定する : dictObj[key] = value
- キーが存在しない場合のみキーに対応する値を設定する : dictObj.setdefault( key, value )
- 項目を削除する : dictObj.pop( key )
- すべての項目を削除する : dictObj.clear()
- 項目(key,value)のリストを取得する : dictObj.items()
- キーのリストを取得する : dictObj.keys()
- 値のリストを取得する : dictObj.values()
- 数値
- 文字列
- ユニコード(UTF-8)
- 正規表現
- ファイル
- ファイルの存在チェック : os.path.exists( path )
- ファイル読み込み
- ファイル書き込み : with open( filePath, 'w' ) as openFile: openFile.write( writeData )
- ファイル削除 : os.remove( path )
- ファイルコピー : shutil.copy2( src, dst )
- ファイル名変更 : os.rename( src, dst )
- ファイル移動 : shutil.move( src, dst )
- ファイル更新日取得 : os.stat( path ).st_mtime
- ファイル更新日変更 : os.utime( path, (atime, mtime) )
- 指定のディレクトリ内のファイルリストを取得 : os.listdir( path )
- 指定のディレクトリ内のファイルを再帰的に走査する : os.walk( path )
- ディレクトリ
- パス操作
- パスをつなげる : os.path.join( 'aaa', 'bbb' )
- ファイルパスから絶対パスを取得する : os.path.abspath( path )
- ファイルパスからファイル名(拡張子付き)を取得する : os.path.basename( path )
- ファイルパスからファイル名(拡張子なし)を取得する
- ファイルパスからディレクトリ名を取得する
- ファイルパスからディレクトリパスを取得する : os.path.dirname( path )
- ファイルパスから拡張子を取得する : os.path.splitext( path )[1]
- ファイルパスがディレクトリを指しているかどうかを取得する : os.path.isdir( path )
- 日付と時間
- 外部コマンドを実行 : subprocess.call( commandList )
- 外部コマンドを実行(標準出力は表示しない)
- 環境変数の取得 : os.environ['PATH']
- 例外
- デバッグ(pdb)
- デバッガコマンド(pdb)
- JSON
- YAML
- クリップボード : pyperclip.copy( value ); value = pyperclip.paste()
リンク
言語機能
型を判定する : isinstance( value, type )
if isinstance( value, str ): # valueが文字列の場合 pass
ドキュメント :
isinstance(組み込み関数)
参照が同じかどうかを判定する : is演算子
if a is b: # 変数aと変数bが同じオブジェクトを参照しているかどうか pass
ドキュメント:
is
for文でインデックスも利用する : for i, v in enumerate( hoge ):
strList = ['ne', 'ushi', 'tora'] for i, v in enumerate( strList ): print( 'Index: {}, value: {}'.format( i, v ) )
ドキュメント :
enumerate(組み込み関数)
2つのリストをfor文で走査する : for (a, b) in zip( listA, listB ):
for (a, b) in zip('abc', '12345'): print( '{}:{}'.format( a, b ) )
出力
a:1 b:2 c:3
ドキュメント :
zip(組み込み関数)
イテレータブルオブジェクト(list,dictなど)
特定の要素を削除(=特定の条件でフィルタリング)
import itertools hogeList = list( itertools.ifilter( lambda x: 条件, hogeList ) )
ドキュメント :
itertools
辞書
ドキュメント :
マッピング型
辞書を作成する : {key:value}
a = {'one': 1, 'two': 2, 'three': 3} # 一般的な方法 b = dict(one=1, two=2, three=3) # dictコンストラクタでキーワード引数 c = dict([('two', 2), ('one', 1), ('three', 3)]) # 2要素iterable(これがキーと値になる)のiterableを渡して作成 assert( a == b == c )
空辞書を作成する : {}
{} # 空辞書を作成 dict() # これも空の辞書
項目数を取得する : len(dictObj)
print( len( {'apple':100,'orange':200} ) ) # 2
キーが存在するかどうかを取得する : key in dictObj
dictObj = {'apple':100,'orange':200} print( 'banana' in dictObj ) # False
キーに対応する値を取得する : dictObj.get( key )
dictObj = {'apple':100,'orange':200} print( dictObj.get( 'orange' ) ) # 200 print( dictObj.get( 'banana' ) ) # None # キーが存在しない場合の値を設定することもできる(設定しない場合はNoneになる) print( dictObj.get( 'apple', 400 ) ) # 100 print( dictObj.get( 'banana', 400 ) ) # 400 # []でのアクセスだとキーが存在しない場合、KeyErrorが発生してしまう # print( dictObj['banana'] )
ドキュメント :
dict.get
キーに対応する値を設定する : dictObj[key] = value
dictObj = {'apple':100,'orange':200} dictObj['banana'] = 400
キーが存在しない場合のみキーに対応する値を設定する : dictObj.setdefault( key, value )
setdefaultメソッドはキーが存在しない場合に値をセットします。戻り値は最終的なキーに対応する値です。
dictObj = {'apple':100,'orange':200} print( dictObj.setdefault( 'apple', 400 ) ) # 100 print( dictObj.setdefault( 'banana', 400 ) ) # 400
ドキュメント :
dict.setdefault
項目を削除する : dictObj.pop( key )
popメソッドはkeyを削除しその値を返します。del文でも項目を削除できますが、KeyErrorの発生を回避できるpopメソッドの方が良さそうです。
dictObj = {'apple':100,'orange':200} print( dictObj.pop( 'apple' ) ) # 100 # キーが存在しなかった場合KeyErrorが発生してしまうが、デフォルト値を渡すことで回避できる print( dictObj.pop( 'banana' ) ) # KeyErrorが発生してしまう print( dictObj.pop( 'banana', None ) ) # None # del文でも項目を削除できるが、キーが存在しなかった場合KeyErrorが発生してしまう del dictObj['apple']
ドキュメント :
dict.pop
すべての項目を削除する : dictObj.clear()
dictObj = {'apple':100,'orange':200} dictObj.clear()
ドキュメント :
dict.clear
項目(key,value)のリストを取得する : dictObj.items()
dictObj = {'apple':100,'orange':200} print( dictObj.items() ) # [('orange', 200), ('apple', 100)]
ドキュメント :
dict.items
キーのリストを取得する : dictObj.keys()
dictObj = {'apple':100,'orange':200} print( dictObj.keys() ) # ['orange', 'apple']
ドキュメント :
dict.keys
値のリストを取得する : dictObj.values()
dictObj = {'apple':100,'orange':200} print( dictObj.values() ) # [200, 100]
ドキュメント :
dict.values
数値
ランダムな値を取得
print( random.randrange( 10 ) ) # 0〜9のランダムな数値 print( random.randrange( 1, 11 ) ) # 1〜10のランダムな数値
ドキュメント :
random.randrange
range
文字列
ドキュメント :
文字列メソッド
シーケンス型メソッド
整数を文字列化
# 普通に文字列化 print( str(10) ) # 10 # 16進数 print( hex(10) ) # 0xa # 書式で文字列化 print( '{:x}'.format( 10 ) ) # a print( '{:X}'.format( 10 ) ) # A print( '{:02x}'.format( 10 ) ) # 0a print( '{:04X}'.format( 10 ) ) # 000A
書式を利用する
'{hoge}'.format( hoge='aaa' )
ドキュメント :
書式指定文字列の文法
文字列フォーマット操作 : %を使った古い方法
2つの文字列の先頭からの文字の一致数を数える
def GetMatchLength( str1, str2 ): ret = 0 for (c1, c2) in zip(str1, str2): if c1 == c2: ret += 1 else: break return ret print( GetMatchLength( 'abc123', 'abcdef' ) ) # 3
ユニコード(UTF-8)
ドキュメント :
Unicode HOWTO — Python 2.7.14 ドキュメント
ソースファイルの文字コードを明記する
# -*- coding: utf-8 -*- # ↑をファイルの最初の行(もしくは2行目)に記述する
これを行わないと、u""
による文字列リテラルが正しく解釈されない。
ドキュメント :
PEP 263 -- Defining Python Source Code Encodings | Python.org
標準入出力でUTF-8を利用できるようにする
import sys import codecs sys.stdout = codecs.getwriter('utf_8')(sys.stdout) sys.stderr = codecs.getwriter('utf_8')(sys.stderr)
ドキュメント :
codecs.getreader
str型をunicode型に変換する
str_text = 'あいうえお' unicode_text = unicode( str_text, 'utf_8' )
ドキュメント :
unicode(標準関数)
unicode型をstr型に変換する
unicode_text = u'あいうえお' str_text = unicode_text.encode('utf-8') print( type(str_text) ) # <type 'str'>
ドキュメント :
str.encode
ユニコード型
ユニコードの正規化を行う
import unicodedata unicodedata.normalize("NFC", unicode_text )
ユニコード文字列は同じ文字でも複数の内部表現ができる場合があります。このような場合、Pythonは見た目上全く同じ文字列でも内部表現の違いで別の文字列と判断してしまいます。これを避けるためにはユニコード文字列に対して正規化という処理を施し、内部表現に違いがでないようにします。ユニコードの内部表現の違いが現れる場面としては、Mac上のファイル名を扱うときがあります。Macのファイルシステムは日本語の濁点が付いた文字を2つの文字(コードポイント)で表す方式(NFD)を採用していますが、この方式は一般的ではないので、見た目が同じで内部表現が違う文字列というのが出てきてしまいます。なので、Mac上のファイル名を取得した場合は、一般的なNFC方式に正規化してから扱う方がいいかもしれません。ちなみに、NFKC方式でも濁点問題を解決できますが、半角カナが全角カナにされてしまうことに注意が必要です。
ドキュメント :
unicodedata.normalize
参考 :
Unicode正規化
正規表現
正規表現で検索
import re p = re.compile('.*\[(.*)\].*') m = re.match( p, 'aiueo[hahaha]' ) print( m.group( 1 ) ) # hahaha
ドキュメント :
正規表現 HOWTO
正規表現で検索して置換
import re # subで置換する方法 p = re.compile('\[(.*)\]') print( re.sub( p, 'ehehe', '123[ohoho]456' ) ) # 123ehehe456 # splitで分割したものを操作し結合(join)する方法 p = re.compile('\[(.*)\]') mlist = re.split( p, '123[ohoho]456' ) mlist[1] = '___' print( ''.join( mlist ) ) # 123___456
ドキュメント :
正規表現 HOWTO
ファイル
ファイルの存在チェック : os.path.exists( path )
import os.path if os.path.exists( path ): pass
ドキュメント :
os.path.exists
ファイル読み込み
import os.path if os.path.exists( path ): with open( path, 'r' ) as openFile: fileData = openFile.read()
もしくは
import os.path import codecs if os.path.exists( path ): with codecs.open( path, 'r', 'utf_8' ) as openFile: fileData = openFile.read()
ドキュメント :
open
codecs.open
ファイル書き込み : with open( filePath, 'w' ) as openFile: openFile.write( writeData )
with open( filePath, 'w' ) as openFile: openFile.write( writeData )
もしくは
import codecs with codecs.open( filePath, 'w', 'utf_8' ) as openFile: openFile.write( writeData )
ドキュメント :
file.write
ファイル削除 : os.remove( path )
import os
os.remove( path )
ドキュメント :
os.remove
ファイルコピー : shutil.copy2( src, dst )
import shutil shutil.copy2( src, dst ) shutil.copy( src, dst ) # メタデータ(ファイル作成日など)をコピーしたくない場合はこっちを使う
ドキュメント :
shutil.copy2
shutil.copy
ファイル名変更 : os.rename( src, dst )
import os
os.rename( src, dst )
srcはディレクトリでも可。
ドキュメント :
os.rename
ファイル移動 : shutil.move( src, dst )
import shutil
shutil.move( src, dst )
srcはディレクトリでも可。
動作的には、srcとdstが同じファイルシステムならos.renameを実行するのみ、別のファイルシステムならファイルをコピー後、srcを削除するらしい。
ドキュメント :
shutil.move
ファイル更新日取得 : os.stat( path ).st_mtime
import os os.stat( path ).st_mtime # os.stat( path )[ST_MTIME] でもアクセス可能
ドキュメント :
os.stat
ファイル更新日変更 : os.utime( path, (atime, mtime) )
import os settime = time.localtime() os.utime( path, (settime, settime) ) # 引数として(最終アクセス時刻,最終更新時刻)のタプルを与える # os.utime( path, None ) # Noneを与えた場合、現在時刻がセットされる
ドキュメント :
os.utime
指定のディレクトリ内のファイルリストを取得 : os.listdir( path )
import os fileList = [os.path.join( path, i ) for i in os.listdir( path ) if os.path.isfile( os.path.join( path, i ) )]
os.listdirはファイル名(エントリ名)のみのリストを返すので、パスをくっつけている。また、os.listdirはファイルだけでなくディレクトリもリストに含めてしまうのでそれらは取り除いている。
ドキュメント :
os.listdir
指定のディレクトリ内のファイルを再帰的に走査する : os.walk( path )
走査してファイルリストを作成する例
import os fileList = [] for dirpath, dirnames, filenames in os.walk( path ): fileList += [os.path.join( dirpath, i ) for i in filenames]
注意: 走査中はカレントディレクトリを変更してはいけない(byドキュメント)
ドキュメント :
os.walk
ディレクトリ
ディレクトリ作成 : os.mkdir( path )
import os
os.mkdir( path )
ドキュメント :
os.mkdir
ディレクトリ作成( 中間ディレクトリも作成 ) : os.makedirs( path )
import os
os.makedirs( path )
ドキュメント :
os.makedirs
ディレクトリ削除 : shutil.rmtree( path )
import shutil
shutil.rmtree( path )
ドキュメント :
shutil.rmtree
カレントディレクトリの取得 : os.getcwd()
import os
os.getcwd()
ドキュメント :
os.getcwd
カレントディレクトリの変更 : os.chdir( path )
import os
os.chdir( path )
ドキュメント :
os.chdir
パス操作
パスをつなげる : os.path.join( 'aaa', 'bbb' )
基本的に普通に文字列の+
でも問題ないけど、os.path.join
の方が少しだけうまくやってくれる
import os.path os.path.join( 'aaa', 'bbb' ) # aaa/bbb os.path.join( 'aaa/', 'bbb' ) # aaa/bbb
ドキュメント :
os.path.join
ファイルパスから絶対パスを取得する : os.path.abspath( path )
import os.path
os.path.abspath( path )
ドキュメント :
os.path.abspath
ファイルパスからファイル名(拡張子付き)を取得する : os.path.basename( path )
import os.path
os.path.basename( path )
ドキュメント :
os.path.basename
ファイルパスからファイル名(拡張子なし)を取得する
import os.path fileName = '' if os.path.isdir( path ): fileName = os.path.basename( path ) else: fileName = os.path.splitext( os.path.basename( path ) )[0]
ドキュメント :
os.path.basename
os.path.splitext
ファイルパスからディレクトリ名を取得する
import os.path dirName = '' if os.path.isdir( path ): dirName = os.path.basename( path ) else: dirName = os.path.basename( os.path.dirname( path ) )
ファイルパスからディレクトリパスを取得する : os.path.dirname( path )
import os.path os.path.dirname( path ) # pathはファイルパスを想定
ドキュメント :
os.path.dirname
ファイルパスから拡張子を取得する : os.path.splitext( path )[1]
import os.path os.path.splitext( path )[1] # `.txt`など
ドキュメント :
os.path.splitext
ファイルパスがディレクトリを指しているかどうかを取得する : os.path.isdir( path )
import os.path
os.path.isdir( path )
ドキュメント :
os.path.isdir
日付と時間
現在時刻(datetime)を取得 : datetime.datetime.now()
import datetime
currentTime = datetime.datetime.now()
ドキュメント :
datetime.datetime.now
日時(datetime)を秒数に変換
(hogeDateTime - datetime.datetime.min).total_seconds()
文字列から日時(datetime)を作成 : datetime.datetime.strptime( dateStr, '%Y/%m/%d' )
import datetime dateStr = '2017/11/20' dateTime = datetime.datetime.strptime( dateStr, '%Y/%m/%d' )
ドキュメント :
datetime.datetime.strptime
日時(datetime)を文字列化 : datetime.strftime( '%Y/%m/%d' )
import datetime nowDateTime = datetime.datetime.now() dateStr = nowDateTime.strftime( '%Y/%m/%d' )
ドキュメント :
datetime.datetime.strftime
電子メールやHTTPの日付文字列(RFC 2822 形式)の変換
import email.utils # 日付文字列から時間(秒)へ変換 timeValue = email.utils.mktime_tz( email.utils.parsedate_tz( 'Mon, 13 Nov 2017 01:23:45 -0000' ) ) # 時間(秒)から日付文字列へ変換 timeStr = email.utils.formatdate( timeValue )
ドキュメント :
email.utils
外部コマンドを実行 : subprocess.call( commandList )
import subprocess
subprocess.call( commandList )
ドキュメント :
subprocess.call
外部コマンドを実行(標準出力は表示しない)
外部コマンドの標準出力を表示しないようにしつつ、標準出力の内容を取得できる
p = subprocess.Popen( commandList, stdout=subprocess.PIPE ) (stdoutStr, stderrStr) = p.communicate()
ドキュメント :
subprocess.Popen
環境変数の取得 : os.environ['PATH']
import os os.environ['PATH']
ドキュメント :
os.environ
例外
ドキュメント :
エラーと例外
例外を捉える
import sys try: # 例外処理対象となる節 pass except ErrorA: # 特定の例外をキャッチ pass except (ErrorB, ErrorC): # 複数の例外をキャッチ pass except ErrorD as e: # 特定の例外をキャッチ( そして例外インスタンスを変数で受け取る ) pass except ErrorF, e: # except ErrorF as e:と同義。(古い文法であり後方互換のための記法) pass except: # その他の例外をキャッチ print "Unexpected error:", sys.exc_info()[0] # sys.exc_info()はタプルで中身は(例外の型, 例外の引数, トレースバック)です raise # 例外を再送出 else: # 例外が発生しなかった場合に実行される節(省略可能) pass finally: # 例外発生の有無によらず必ず最後に実行される節(省略可能) pass
ドキュメント :
例外を処理する
例外を発生させる
try: raise NameError( 'ahaha' ) # 例外を発生させる except NameError: raise # 例外を再送出する
ドキュメント :
例外を送出する
捕捉されなかった例外を捉える : sys.excepthook
import sys def my_except_hook(exctype, value, traceback): print( 'Exception! Yeah!:{}'.format( exctype ) ) sys.__excepthook__(exctype, value, traceback) sys.excepthook = my_except_hook print( 'hoge' + 5 ) # 例外が発生
出力
標準出力 Exception! Yeah!:<type 'exceptions.TypeError'> 標準エラー Traceback (most recent call last): File "prog.py", line 7, in <module> TypeError: cannot concatenate 'str' and 'int' objects
ドキュメント :
sys.excepthook
参考 :
Python Global Exception Handling - Stack Overflow
デバッグ(pdb)
デバッガ付きで実行する : python -m pdb ファイル名.py
スクリプトの実行時に、pythonへの引数として-m pdb
を指定するとデバッガ付きの実行になります。
python -m pdb ファイル名.py
ドキュメント :
pdb
ソースコードにブレークポイントを記述する : import pdb; pdb.set_trace()
ソースコードの任意の場所でブレークポイントでプログラムを止めたい場合、pdb.set_trace()
を呼びます。デバッガ付きの実行でなくても、呼ばれたタイミングでデバッガが起動します。
ドキュメント :
pdb.set_trace
デバッガコマンド(pdb)
コマンド(省略形) | 引数 | 説明 |
---|---|---|
help(h) | コマンド名 | 引数なし : 利用できるコマンドの一覧を表示 引数あり : 引数で指定されたコマンドのヘルプを表示 |
next(n) | ステップ実行(ステップオーバー) | |
step(s) | ステップ実行(ステップイン) | |
return(r) | ステップ実行(ステップアウト) | |
continue(c) | 再開 | |
! | 文(Pythonコード) | Pythonコード(文)を実行。コード先頭の単語がデバッガコマンドと被らない場合、`!`は省略可能 |
p | 式(Pythonコード) | Pythonコード(式)を評価し、結果を出力する |
quit(q) | デバッガ終了。プログラムは中断される |
ドキュメント :
デバッガコマンド
JSON
import json # JSON読み込み with open( filePath ) as f: jsonData = json.load(f) # JSON書き込み with open( filePath, 'w' ) as f: f.write( json.dumps( jsonData, indent=4 ) )
ドキュメント :
json
YAML
標準ライブラリではYAMLを扱えないので、外部モジュールのPyYAML
をインストールする。
# コマンドライン pip install PyYAML
import yaml # YAML読み込み with open( filePath ) as f: yamlData = yaml.load(f) # YAML書き込み with open( filePath, 'w' ) as f: f.write( yaml.dump( yamlData ) )
ドキュメント :
PyYAMLDocumentation
クリップボード : pyperclip.copy( value ); value = pyperclip.paste()
標準ライブラリではクリップボードを扱えないので、外部モジュールのpyperclip
をインストール。
# コマンドライン pip install pyperclip
import pyperclip # コピー pyperclip.copy('abcdef') print( pyperclip.paste() ) # abcdef
ドキュメント:
pyperclip · PyPI