みろりHP


緑色さんの多目的ブログ
みろりえいちぴー
ごゆるりとおくつろぎあさーせ。
<< アコギ ICO『Castle in the mist』 | main | アコギスタートセット >>
| カテゴリ:プログラミング |
Brett Slatkin『Effective Python』その1 Python流思考



いえーい。最近はPythonの気分なので、その流れで読むぜ。面白かったとこをノートするいつものノリで。




PEP8をまもれ!
Python本はこればっかですね! 先日までSublime Text3にPEP8のチェッカーパッケージを入れていたんだけど、「ほかのひとのコードをネットからコピペしたときペケだらけになって非常に見づらい」「関数間を2行空ける」の2点がイヤでヤメちまった。まあ基本的なところは守っているぜ。
例として記載されていたなかで目新しかったのが下記ふたつ。
len(lis) == 0
ではなく
not lis
を使いましょう。
・import文は標準モジュール、サードパーティ、自前のモジュールの順番に記載する。

PEP8で気に入ってるやつ
コーディング規約ってのは、知ると目ウロコなものがたくさんある。とくに気に入ってるのが、「一行は79文字以下におさめましょう」ってやつ。これを守るとスクリプトがスッキリして見える。積極的に守っていきたい。
どうしても行が長くなることってあるじゃん? クラス名もメソッド名も長いから書こうとしたらどうしても幅とっちゃうんだよー、とか引数が多いから仕方ないじゃん、とか入れ子が多くなればなるほどインデントが増えるんだからどうしようもないじゃんとか。でもさ、そういうときコーディング規約はこう言ってくるんだよ。「そういうときは設計がおかしい。」この発想は気に入った。そもそも名前は短いほうがいいし、引数はなるたけ少なくするのが基本だし、forとかifの入れ子は少なくするべきだ。

文字列型の bytes と str を知っておく。
文字列型には上記ふたつがあって、それぞれ変換は……
bytes_.decode('UTF8')  # str化
str_.encode('UTF8')    # bytes化
ほんでバイナリファイルの読み書きでは、open関数のオプションに rb とか wb を使うこと。まあそれはいいけどバイナリファイルなんてどんなときにいじるのか俺には想像がつかん。アレだろバイナリって、0と1だけの……。

ディクショナリ.get(キー, None)
キーがなければNoneを返す、というディクショナリのメソッド。うわこれ知らんかった、便利そうだ。

ヘルパー関数を使いましょう。
Pythonは複雑で読みづらい式を1行で書きやすい。そういうときは行を分けて読みやすくして、それをヘルパー関数にまとめましょう。最近高階関数を覚えて大はしゃぎでコードを難読化してる俺には耳が痛いお話です。

スライスを使おう!
lis[0:5]
lis[:5]
は同じ。後者を使いましょう。うへえ、0書いてたわあ。
[::2]
みっつめにはstride……なん文字ごと、が指定できる。

スライスではstart,end,strideをいっしょに使うな。
lis[2:10:2]
はダメ。わかりづらいから。やるなら2行に分けること。

mapやfilterの代わりにリスト内包表記を使おう!
そうか……mapやfilterって、内包表記に置き換えることができるのか。これは目ウロコだ。
a = [0, 1, 2, 3, 4, 5]

# だよんをつける map版
print(list(map(lambda i: f'{i}だよん', a)))

# だよんをつける 内包表記
print([f'{i}だよん' for i in a])
# ↓どちらもこうなる
['0だよん', '1だよん', '2だよん', '3だよん', '4だよん', '5だよん']
# 奇数のみ filter版
print(list(filter(lambda i: i%2 == 1, a)))

# 奇数のみ 内包表記
print([i for i in a if i%2 == 1])
# どちらもこうなる
[1, 3, 5]
……ってことか。この例ではだけど、内包表記を使えば文字数は短くなるし、わざわざlist()を使わなくて済む。逆に結果をイテレータのままにしたい場合はmap、filterの使い所だろうね。
mapとかfilter、内包表記をさらっと書ける自分に成長を感じる! いやあプログラムはじめてから2年たってるもんなあ。

内包表記ではforを重ねることもできるぞ!
rows = [
    [0, 1, 2],
    [3, 4, 5],
]

# 二重forバージョン
_ = []
for row in rows:
    for r in row:
        _.append(r)
print(_)

# 内包表記バージョン
print([r for row in rows for r in row])
# どっちもこうなる
[0, 1, 2, 3, 4, 5]
ただし3つ以上になったらヤメとくこと。読みづらくなるから、ヘルパー関数とか使いましょう。
ところで二重の内包表記の書く順番ってちょっと間違えやすくない? 最初forを二重に内包表記って聞いて、こうかと思った。
[r for r in row for row in rows]

作ろうとしてるリストがバカでかくなっちゃうときは、ジェネレータを使おう!
lis = [i for i in range(10000000000)]
こんなことしたら10000000000個要素が詰まったリストが生成されてメモリが爆発しちゃいそうじゃん? そんなときは
gene = (i for i in range(10000000000))
こうする。中身の取り出しは
next(gene)
これでいっこずつ取り出せる。lis[10]みたいに途中の要素を取り出すことができないのが難点かな? でもでっけえリストを生成しないってのはイイね。

連鎖ジェネレータはすげえ高速。
gene  = (a for a in open('foo.txt', 'r', encoding='UTF8'))
gene2 = (a.strip() for g in gene)

enumerate()の使い所は……リストを回したいが添字も欲しいとき!
for i, value in enumerate(lis, 1):
    print(i, value)
こういうこと。enumerateに第二引数を指定すれば、iがその数からスタートになる。別にlis[1]からスタートってわけじゃない。これ便利ね。

複数のイテレータを回したいならzip()を使うこと。
ああー、これは言われなくても知ってるよー。
# ただしイテレータの長さが違うと、片方が終わったところで終了しちゃう。
# それがイヤなときは itertools.zip_longest() を使うこと。
それはまったく知りませんでしたすみません。

for - else っていう構文がある。
へー! しらなかった!
# が、それは振る舞いが直感的じゃないから使うな。
えー!?

try, except, else, finally の使い分け。
try: 例外が起こるかもしれないコード
except: 例外が起こったときやること
else: tryが成功したときすること。ここをしっかり書いて、tryブロックを最小にしよう!
finally: file.close()など後始末を。「たとえelseでreturnが起こってもこのブロックは実行される。」へぇえー!!

| 緑色 | プログラミング | comments(0) |
| カテゴリ:- |
スポンサーサイト
| スポンサードリンク | - | - |









   1234
567891011
12131415161718
19202122232425
262728293031 
<< August 2018 >>
+ みろりHP内検索
+ 閲覧記事
+ 過去記事アーカイブ
+ 年月選択
  • 2018年 07月 (6)
  • 2018年 06月 (5)
  • 2018年 05月 (4)
  • 2018年 04月 (7)
  • 2018年 03月 (6)
  • 2018年 02月 (6)
  • 2018年 01月 (8)
  • 2017年 12月 (9)
  • 2017年 11月 (9)
  • 2017年 10月 (4)
  • 2017年 09月 (6)
  • 2017年 08月 (6)
  • 2017年 07月 (8)
  • 2017年 06月 (4)
  • 2017年 05月 (7)
  • 2017年 04月 (8)
  • 2017年 03月 (7)
  • 2017年 02月 (10)
  • 2017年 01月 (6)
  • 2016年 12月 (8)
  • 2016年 11月 (8)
  • 2016年 10月 (5)
  • 2016年 09月 (5)
  • 2016年 08月 (7)
  • 2016年 07月 (9)
  • 2016年 06月 (6)
  • 2016年 05月 (8)
  • 2016年 04月 (10)
  • 2016年 03月 (10)
  • 2016年 02月 (8)
  • 2016年 01月 (9)
  • 2015年 12月 (9)
  • 2015年 11月 (6)
  • 2015年 10月 (5)
  • 2015年 09月 (4)
  • 2015年 08月 (8)
  • 2015年 07月 (5)
  • 2015年 06月 (3)
  • 2015年 05月 (7)
  • 2015年 04月 (8)
  • 2015年 03月 (12)
  • 2015年 02月 (8)
  • 2015年 01月 (4)
  • 2014年 12月 (5)
  • 2014年 11月 (5)
  • 2014年 10月 (7)
  • 2014年 09月 (4)
  • 2014年 08月 (7)
  • 2014年 07月 (6)
  • 2014年 06月 (4)
  • 2014年 05月 (12)
  • 2014年 04月 (9)
  • 2014年 03月 (6)
  • 2014年 02月 (6)
  • 2014年 01月 (8)
  • 2013年 12月 (7)
  • 2013年 11月 (10)
  • 2013年 10月 (10)
  • 2013年 09月 (9)
  • 2013年 08月 (11)
  • 2013年 07月 (10)
  • 2013年 06月 (9)
  • 2013年 05月 (15)
  • 2013年 04月 (11)
  • 2013年 03月 (5)
  • 2013年 02月 (7)
  • 2013年 01月 (6)
  • 2012年 12月 (9)
  • 2012年 11月 (10)
  • 2012年 10月 (10)
  • 2012年 09月 (4)
  • 2012年 08月 (2)
  • 2012年 07月 (7)
  • 2012年 06月 (13)
  • 2012年 05月 (13)
  • 2012年 04月 (15)
  • 2012年 03月 (4)
  • 2012年 02月 (12)
  • 2012年 01月 (9)
  • 2011年 12月 (5)
  • 2011年 11月 (13)
  • 2011年 10月 (2)
  • 2011年 09月 (2)
  • 2011年 08月 (1)
  • 2011年 06月 (1)
  • 2011年 05月 (4)
  • 2011年 04月 (10)
  • 2011年 03月 (8)
  • 2011年 02月 (11)
  • 2011年 01月 (14)
  • 2010年 12月 (14)
  • 2010年 11月 (17)
  • 2010年 10月 (17)
  • 2010年 09月 (19)
  • 2010年 08月 (22)
  • 2010年 07月 (18)
  • 2010年 06月 (16)
  • 2010年 05月 (19)
  • 2010年 04月 (15)
  • 2010年 03月 (22)
  • 2010年 02月 (18)
  • 2010年 01月 (18)
  • 2009年 06月 (2)
  • 2007年 12月 (10)
  • 2007年 11月 (7)
  • 2007年 10月 (9)
  • 2007年 09月 (4)
  • 2007年 07月 (5)
  • 2007年 06月 (11)
  • 2007年 05月 (6)
  • 2007年 04月 (4)
  • 2006年 01月 (21)
  • + カテゴリ
    + ブックマーク
    + 最近のコメント
    + アクセスカウンター
    全体(since 2010.02.03.)
    今日… 昨日…