【書評】入門Python3 :とりあえず読んでおくべき
ある程度pythonを触った身からすると、読んでおいて損はない本。
- 作者:Bill Lubanovic
- 発売日: 2015/12/01
- メディア: 単行本(ソフトカバー)
これが全く触ったことがな人だともしかしたら読みづらいかもしれない。 そもそもオラ本が全般的に初心者に易しくない気はする(head firstシリーズは易しい?)。
上記に当てはまる場合(自分はそう)は、間違いなく優良な本だった。 というのは、やはり実践主義でコードを書いていると、変な癖がつく気がしていて、 それはpythonのポリシーと合っているかわからないし、そもそも無駄な実装をしている可能性もあり、 標準ライブラリを使えば簡単に解決できるのではないか、という不安を抱いて、 この本を読んだらその不安が的中していたからである。
例えば、setクラスはずっと重複なしリストだと思い込んでいた。 「リストから重複を除外したい」と調べたら大体setを使った解法が出てくるため、 そのために作られたクラスなのだと思い込んでしまっていた。実際は集合クラスなので集合演算ができる。 他にもcsvにあるDictReaderやDictWriterも便利だなと思った(pandas使う場面が多いけど)。
とはいえ、イディオムやデザインパターンなどの内容は書いていないため、 この本を読めばシステム開発ができるとまではいかない。 にしても、どのような道具があるのかを知ることできるし、どの場面で使えばいいのかもわかるため、 今後pythonを触るエンジニアは早めに読むことをおすすめする。
個人的付箋
集合クラス
setは集合クラス。重複なしリストかと思ってたが違った。 なので集合演算ができる。
a = {1, 2} b = {2, 3} a & b a.intersection(b) a + b a.union(b)
elseによるbreakチェック
whileやforは、正常終了したかどうかをチェックするオプションのelseを持っている。 ループがbreak呼び出して途中で終了しておらず、最後まで実行されたときにelse内が実行される。
for c in cs: print('hoge') break else: # breakしていない print('fuga')
例外
exrcept exceptiontype as name
short_list = [1, 2, 3] while True: value = input('Position [ q to quit ] ? ') if value = 'q': break try: position = int(value) print(short_list[position]) except IndexError as err: print('Bad index:', position) except Exception as other: print('Something else broke:' other)
存在しないキーの処理
存在しないキーで辞書にアクセスする際の振る舞いについて、 get()関数を使ってデフォルト値を返すようにすれば例外を避けられる。 setdefault()関数はキーがなければさらに辞書を要素に追加することができる。
periodic_table = {'Hydrogen' : 1, 'Helium' : 2} carbon = periodic_table.setdefault('Carbon', 12) # carbon => 12 # periodic_table => {'Hydrogen' : 1, 'Helium' : 2, 'Carbon', 12} # すでにキーがある場合は更新されない helium = periodic_table.setdefault('Helium', 923) # helium => 2 # periodic_table => {'Hydrogen' : 1, 'Helium' : 2, 'Carbon', 12}
defaultdictは辞書作成時にあらゆる新キーのためにあらかじめデフォルト値を設定する。
from collections import defaultdict periodic_table = defaultdict(int) periodic_table['Hydrogen'] = 1 periodic_table['Lead'] periodic_table # defaultdict(<class 'int'>, {'Lead': 0, 'Hydrogen': 1})
特殊メソッド
比較のための特殊メソッド
メソッド | 意味 |
---|---|
__eq__( self, other ) | self == other |
__ne__( self, other ) | self != other |
__lt__( self, other ) | self < other |
__gt__( self, other ) | self > other |
__le__( self, other ) | self <= other |
__ge__( self, other ) | self >= other |
算術演算のための特殊メソッド
メソッド | 意味 |
---|---|
__add__( self, other ) | self + other |
__sub__( self, other ) | self - other |
__mul__( self, other ) | self * other |
__floordiv__( self, other ) | self // other |
__truediv__( self, other ) | self / other |
__mod__( self, other ) | self % other |
__pow__( self, other ) | self ** other |
その他の特殊メソッド
メソッド | 意味 |
---|---|
__str__( self, other ) | str(self) |
__repr__( self, other ) | repr(self) |
__len__( self, other ) | len(self) |
下記でドキュメント化されている。
https://docs.python.org/3/reference/datamodel.html#special-method-names
Guidoのアドバイス
データ構造を作り込みすぎないようにしよう。オブジェクトよりもタプルの方がいい。ゲッター/セッター関数よりも単純なフィールドを選ぶようにしよう。組み込みデータ型はプログラマーの友達だ。数値、文字列、タプル、リスト、集合、辞書をもっと使おう。そして、コレクションライブラリ、特にデックをチェックしよう。
collections --- コンテナデータ型 — Python 3.8.3 ドキュメント
名前つきタプル
from collections import namedtuple Duck = namedtuple( 'Duck', 'bill tail' ) duck = Duck('wide orange', 'long') # duck => Duck(bill='wide orange', tail='long) # duck.bill => wide orange # duck.tail => 'long'
csv
DictReaderを使って辞書リストにすることができる。 各行のキーが、各列のヘッダーとなる。
import csv with open('villains', 'rt') as fin: cin = csv.DictReader(fin, fieldname=['first', 'last']) villanins = [row for row in cin]
DictWriterを使って辞書リストからヘッダー付きのcsvファイルを作成することができる。
with open('dst_villains', 'wt') as fout: cout = csv.DictWriter(fout, ['first', 'last'] cout.writeheader() cout.writerows(villains)
yaml
PyYAMLは文字列からPythonオブジェクトをロードできるが、これは危険なことだ。 load()ではなくsafe_load()を使うべき。
timedelta
from datetime import date, timedelta now = date.today() one_day = timedelta(day=1) tomorrow = now + one_day yesterday = now - one_day # 17日後 now + 17 * one_day
リスト内表記はappend()を使ったリストへの要素追加より速い
result =[] for value in range(1000): result.append(value) # こちらのほうが2倍以上速い result = [value for value in range(1000)]