koji/メガネ男の日誌

日々の学び、活動状況を記録します。仕事のことは少なめ。

Effective Python(第2版) 1章を読み込んだ

f:id:kj_man666:20200810095316j:plain

Challeng-Every-Monthというコミュニティで、みんなで Effective Python を読み合うイベントに参加しています。

その学びをまとめたいと思います。

なお、Effective Pythonの .py コードがGitHubに公開されています。

また、jupyter でコードを確認したい場合は、まだ1章だけですがこちらに公開しましたのでご利用ください。

わかったこと

 - 色んな書籍で、インデントの強制といった可読性を向上させるための仕組みが python ではルール化されていることは知っていましたが、公式テキストの中でこのように考え方が述べられているのは初めて知りました。

 また、下記のコマンドを入力すれば python の考え方が出力されるとは徹底されていますね。

# The zen of python の表示
import this

qiita.com

  • 項目04よりprint() 内での変数の表示

 - "%s/d/f", 変数

www.javadrive.jp

 - "{0}".format(変数)

 - f "{変数}"

 これらの表現があることは知っていましたが、可読性の向上のためにバージョンを追うごとに追加された仕組みであることを初めて知りました。

 これからは可読性を意識して f "{変数}" を使用していきたいと思います。

  • 項目07よりyield

yieldについては単語が触れられているだけですが、

ailaby.com

def func():
    a = 10
    b = 20
    c = a + b
    yield c      # ここで一旦停止
 
    a = 100
    b = 200
    c = a + b
    yield c      # ここで一旦停止
 
    a = 1000
    b = 2000
    c = a + b
    yield c      # ここで一旦停止
 
 
for x in func():
    print (x)

出力 : 30 300 3000

ちなみにreturnで同じことをやろうとするとエラーになります。

def func():
    a = 10
    b = 20
    c = a + b
    return c    
 
    a = 100
    b = 200
    c = a + b
    return c    

    a = 1000
    b = 2000
    c = a + b
    return c  
  
for x in func():
    print (x)

出力 : TypeError: 'int' object is not iterable

qiita.com

for i in range(len(values_list)):
    list_2[i]
for index_num, values in enumerate(list):
for i, j in zip(values_list, index_num_list):

こちらもこれらの表現があることは知っていましたが、可読性の向上のためにバージョンを追うごとに追加された仕組みであることを初めて知りました。

可読性を意識して for ~ in zip(A, B) を使用していきたいと思います。

  • 項目09よりループ後のelse の挙動 (非推奨)

while のようなループ後にelse文を設定すると、ループ終了後にelse文が実行されます。

j = 0
while j < 5:
    j = j + 1
    print(j)
else:
    print("finished!")

出力 : 1 2 3 4 5 finish!

しかし breakが作動すると、else文は実行されないようです。

j = 0
while j < 5:
    j = j + 1
    print(j)
    if j > 3:
        break
else:
    print("finished!")

出力 : 1 2 3 4

breakも途中で終了させる機能なのに、なぜかelse文は実行されず、ピンときませんね。

そのため挙動がわかりにくく非推奨、とEffective Pythonには記載されています。

  • 項目10より := (ウォルラス演算子

python バージョン3.8より追加された変数に値を割り当てる新しい構文。

www.lifewithpython.com

例えば下記のような構文があるとします。

text = "Happy New Year!"
if len(text) < 20:
    print(f"{text} is {len(text)} word count! {len(text)} is lucky number!" )
else:
    print("stack over!")

出力 : Happy New Year! is 15 word count !

len(text)を何回も打ち込んでいるので、可読性が下がってしまいます。

そこで次のように i = len(text) としてみてはどうでしょうか。

i=len(text)

if i < 20:
    print(f"{text} is {i} word count ! {i} is lucky number!" )
else:
    print("stack over!")

出力 : Happy New Year! is 15 word count !

print()内はスッキリしましたが、i=len(text) と print() 内の間にたくさんコードが書かれてしまうと、 あれ、この i どこで定義したっけ・・・?となる可能性があります。

そこで次のようにするとどうでしょうか。

if (i=len(text)) < 20:
    print(f"{text} is {i} word count! {i} is lucky number!" )
else:
    print("stack over!")

出力 : SyntaxError: invalid syntax

エラーになってしまいます。

python は if 文の条件内で変数の代入ができない仕様なのでした。

これを解決したのが := (ウォルラス)演算子です。

if (i:=len(text)) < 20:
    print(f"{text} is {i} word count ! {i} is lucky number!" )
else:
    print("stack over!")

出力 : Happy New Year! is 15 word count !

無事エラーが出ませんし、i の定義が i を使うprint()の近くにあるので可視性が向上しました。

ちなみにウォルラスとはセイウチのことだそうです。

f:id:kj_man666:20200810093108j:plain

わからなかったこと
  • 項目5 ヘルパー関数

www.ne.jp

ヘルパー関数がコードの中でどういう挙動をするものなのかわかりませんでした・・・。

分かり次第追記したいと思います。

以上になります、最後までお読みいただきありがとうございました。