n4okins / Pythonの小技集

Created Sat, 30 Mar 2024 16:03:17 +0900 Modified Sat, 30 Mar 2024 16:03:17 +0900

Pythonの小技集

f文字列の裏技

f文字列はPython3.6から導入された機能で、文字列の中に変数を埋め込むことができる。

a = 123
b = 45.678
print(f"{a}, {b}")
print(f"{a:05d}, {b:.2f}") # format文と一緒
123, 45.678
00123, 45.68

実は、=を使うことで変数名や式の内容と中身を同時に表示することができる。

a = 123
b = 45.678
print(f"{a=}, {b=}")
print(f"{a=:05d}, {b=:.2f}") # format文と一緒
a=123, b=45.678
a=00123, b=45.68

こんなこともできる。

import numpy as np
print(f"{np.array([0, 1, 2])=}")
np.array([0, 1, 2])=array([0, 1, 2])
import numpy as np
print(f"{(lambda x: x**2)(np.array([0, 1, 2]))=}")
(lambda x: x**2)(np.array([0, 1, 2]))=array([0, 1, 4])

変数の中身を確認するときに便利。

2のn乗の書き方(左シフト)

n = 3
print(1 << n)
8

1を3ビットだけ左にシフトすることで、1000が得られる。これは2**3と等しい。

typeで動的なクラス作成

type()はクラスを確認するだけでなく、クラスを作成することもできる。

class MyClassBase:
    def __init__(self, name):
        self.name = name
    
    def __repr__(self):
        return f"<{self.__class__.__name__} ({self.name})>"

classes = []
for i in range(3):
    classes.append(type(f"MyClass{i}", (MyClassBase,), {}))

print(classes)
[<class '__main__.MyClass0'>, <class '__main__.MyClass1'>, <class '__main__.MyClass2'>]

こんな感じで連番のクラスも作れる。 何に使うの?

lambda式で変数の中身を確認しつつ処理を継続

f = lambda x: print(f"input: {x=}") or x**2
print(f(3))
input: x=3
9

print関数の戻り値がNoneであること、or演算子は短絡評価であることを利用している。

無限イテレータ

n = iter([1, 2, 3])
for _ in range(5):
    print(next(n))
1
2
3
Traceback (most recent call last):
  File "/path/to/main.py", line 3, in <module>
    print(next(n))
StopIteration

通常のiterではイテレータが終了するとStopIterationが発生する。

count = 0
n = iter(lambda: count, None)
for _ in range(5):
    print(next(n))
    count += 1
0
1
2
3
4

iterの第2引数は終了条件を指定できる。今回のようにNoneを指定すると、第1引数の戻り値がNoneになるまで無限に続く。