Tips

[1]:
import numpy as np

f-string

 string 以外の変数の値を文字列に組み込みたい場合、f-string 記法というのがあります。 これは、Python3.6 以上ではないと使えないのに注意してください。 まずは、何も使わない場合。

[2]:
a = 0
b = 2
[3]:
'a の値は ' + str(a)
[3]:
'a の値は 0'
[4]:
'a の値は ' + str(a) + ': a - b の値は ' + str(a - b)
[4]:
'a の値は 0: a - b の値は -2'

変数が一つの場合はまだ楽ですが、二つ、三つとなると面倒です。 実は、format メソッドというものがあり、これを使うことで、文字列に後から変数を代入できます。 format メソッドは Python3.6 より前でも使えます。 変数を代入したい場所に {} をつけます。

[5]:
'a の値は {}: a - b の値は {}'.format(a, a - b)
[5]:
'a の値は 0: a - b の値は -2'

format はキーワード引数も使えます。 こちらのほうが可読性が良いです。

[6]:
'a の値は {a}: a - b の値は {a_b}'.format(a = a, a_b = a - b)
[6]:
'a の値は 0: a - b の値は -2'

f-string 記法はキーワード引数を使ったformat メソッドに似てますが、format メソッドを付ける必要がありません。 代わりに、f を文字列の前につけます (F でも可)。

[7]:
f'a の値は {a}: a - b の値は {a - b}'
[7]:
'a の値は 0: a - b の値は -2'

{} の中の変数はすでに定義されている必要があるのに注意してください。 下はエラーになります。

[8]:
# f'c の値は {c}'

f-string および format はただ変数を代入するだけでなく、より柔軟に文字列の代入をすることができます。 例えば、ゼロ埋め(zero padding)や桁区切りなどが可能です。 {} に代入したい変数名の後に : を入れ、その後に書式を指定します。

[9]:
i = 1234
print(f'zero padding: {i: 06}')
print(f'with conmma :  {i:,}')
zero padding:  01234
with conmma :  1,234

Python の bool 型と Numpy の bool 型の違い

Python と Numpy にはどちらも bool 型がありますが、若干の違いがあります。 論理和などの挙動が一部異なるので、注意してください。

Python の bool 型

Python での bool 型、True, Falseint クラスのサブクラスです。 つまり、True は 1, False は 0 と解釈される場合があります。 実際に見てみましょう。 ビット単位演算子 | は論理和、& は論理積を返します。

[10]:
print(f'True & True   : {True & True}')
print(f'True | True   : {True | True}')
print(f'True & False  : {True & False}')
print(f'True | False  : {True | False}')
print(f'False & False : {False & False}')
print(f'False | False : {False | False}')
True & True   : True
True | True   : True
True & False  : False
True | False  : True
False & False : False
False | False : False

一方で、和 + と差 - も定義されていますが、この場合は数値として計算されます。

[11]:
print(f'True + True   : {True + True}')
print(f'True - True   : {True - True}')
print(f'True + False  : {True + False}')
print(f'True - False  : {True - False}')
print(f'False + False : {False + False}')
print(f'False - False : {False - False}')
True + True   : 2
True - True   : 0
True + False  : 1
True - False  : 1
False + False : 0
False - False : 0

Numpy での bool 型

Numpy での bool 型は int 型のサブクラスではありません。 論理和 |、論理積 & は Python の bool 型と同じです。 ブール演算子 and, or も Python の bool 型と同じになります。

[12]:
true = np.array([True])
false = np.array([False])
[13]:
print(f'True & True   : {true & true}')
print(f'True | True   : {true | true}')
print(f'True & False  : {true & false}')
print(f'True | False  : {true | false}')
print(f'False & False : {false & false}')
print(f'False | False : {false | false}')
True & True   : [ True]
True | True   : [ True]
True & False  : [False]
True | False  : [ True]
False & False : [False]
False | False : [False]

 一方で、和 + は論理和と同じであり、差 - は定義されません。

[14]:
print(f'True + True   : {true + true}')
# print(f'True - True   : {true - true}')
print(f'True + False  : {true + false}')
# print(f'True - False  : {true - false}')
print(f'False + False : {false + false}')
# print(f'False - False : {false - false}')
True + True   : [ True]
True + False  : [ True]
False + False : [False]

ただし、どちらの bool 型も 数値型(intfloatなど)と足し引きができます。

[15]:
print(f'True + 1: {True + 1}')
print(f'True - 1: {True - 1}')
print(f'np.array([True]) + 1: {np.array([True]) + 1}')
print(f'np.array([True]) - 1: {np.array([True]) - 1}')
True + 1: 2
True - 1: 0
np.array([True]) + 1: [2]
np.array([True]) - 1: [0]

したがって、どちらも sum を使えば、True の数をカウントすることができます。 これは、sum 関数が default で 0 を最初に足しているからです。 なお、numpysum メソッドも同じです。

[16]:
a = [True, False, True, True]
b = np.array([True, True, False, False])
print(sum(a))
print(sum(b))
print(b.sum())
3
2
2

三項演算子

if ~ else はインデント・ブロックが必要なため、どうしてもコードが長くなってしまいます。 三項演算子を使えば、1行で書くことができます。 次のように書きます。 変数 = 真の場合の値 if 条件式 else 偽の場合の値

[17]:
b = 5 if 3 == 3 else 9 # True
# 下のコードは上と同じ
# if 3 == 3:
#     b = 5
# else:
#     b = 9
b
[17]:
5

長い文の場合は可読性が悪くなるので、使い所に注意してください。

内包表記

リスト、辞書などに逐次的に要素を足していく場合には、for ループも1行で書くことができます。 これをリスト内包表記、辞書内包表記と言います。 リスト内包表記は次のように書きます。

[18]:
c = [i for i in range(5)]
# 下と同じ
# c = []
# for i in range(5):
#     c.append(i)
c
[18]:
[0, 1, 2, 3, 4]

辞書内包表記は次のように書きます。

[19]:
d = {i: i for i in range(5)}
d
[19]:
{0: 0, 1: 1, 2: 2, 3: 3, 4: 4}

if を用いて、条件式が真の場合のみ要素を足していくことや、三項演算子を入れることもできます。 if の場合と if ~ else がある場合で少し書き方が違うので注意してください。

[20]:
k = [i for i in range(5) if i % 2 == 0]
# 下と同じ
# k = []
# for i in range(5):
#   if i % 2 == 0:
#       k.append(i)
k
[20]:
[0, 2, 4]
[21]:
j = [i if i % 2 == 0 else 0 for i in range(5)]
# 下と同じ
# j = []
# for i in range(5):
#   if i % 2 == 0:
#       j.append(i)
#   else:
#       j.append(0)
j
[21]:
[0, 0, 2, 0, 4]

三項演算子と同じように、長い文の場合は逆に読みにくくなるので注意してください。 また、内包表記を使うと、append を使うよりも非常に高速に処理を行うことができます。 多くのループ作業が必要な場合は、内包表記か numpy を使うことを考えましょう。 ちなみに、タプル内包表記というのはなく、() の内包表記はジェネレーター内包表記というものになります。

[22]:
(i for i in range(5))

[22]:
<generator object <genexpr> at 0x1120da570>