「Pythonのドキュメントでも読むか～」「え、何その裏技」

:::note info
**追記**
続編記事を書きました↓
[「Python標準ライブラリのドキュメントでも読むか～」「え、何その裏技」](https://qiita.com/CinnamonSea2073/items/2cae34c3dd7ff86d0950)
:::

## 読み飛ばしてください
おはようございます、しなもんです。

Pythonの公式ドキュメントを読んでたら、なんか知らない便利機能がたくさん出てきました。
なんだこれ。

というわけでまとめてみました。
参考になれば幸いです。

## f-stringsの拡張機能

`f-strings`、便利ですよね。大好きです。
そんなあいつには裏技があるみたいです。

### デバッグ用の=演算子

**Python 3.8**以降、`f-string`の中で`=`演算子を使用することで
変数名とその値を同時に表示できるらしい。

```py
x = 10
y = 20
print(f"{x=}, {y=}")  # 出力: x=10, y=20
```

デバッグするときに便利そうです。

### 書式指定オプション

`f-string`では、変数の後ろにコロンを付けることで
様々な書式指定ができるらしい。

```py
pi = 3.14159
print(f"{pi:.2f}")  # 出力: 3.14 (小数点以下2桁まで表示)

number = 1234567
print(f"{number:,}")  # 出力: 1,234,567 (3桁ごとにカンマを挿入)
```

## `collections`モジュール

`collections`モジュール？なんだそれは。
データ構造を扱う上で便利なクラスが用意されているらしい。

### `namedtuple`の動的生成

`namedtuple`は、名前付きフィールドを持つタプルのサブクラスを作成するらしい。
**名前付きのタプル...？なんだと？**

```python
from collections import namedtuple

# フィールド名のリストから動的に生成
fields = ["x", "y", "z"]
Point3D = namedtuple("Point3D", fields)

p = Point3D(1, 2, 3)
print(p.x, p.y, p.z)  # 出力: 1 2 3
```

https://qiita.com/valusun/items/279fe5b69ed3fd91f0b2

つまり
```py
print(hoge[0])
```
ってしてたのが

```py
print(hoge.huga)
```
ってできるのか。

めっちゃ良すぎる。

### `defaultdict`

`defaultdict`は、存在しないキーにアクセスした際の
デフォルト値を指定できる辞書クラスらしい。

```python
from collections import defaultdict

# リストを値とするdefaultdictを作成
group_by_age = defaultdict(list)

people = [("Alice", 25), ("Bob", 30), ("Charlie", 25)]

for name, age in people:
    group_by_age[age].append(name)

print(group_by_age)
# 出力: defaultdict(<class 'list'>, {25: ['Alice', 'Charlie'], 30: ['Bob']})
```

https://qiita.com/xza/items/72a1b07fcf64d1f4bdb7


## 関数デコレータの高度な使い方

デコレータにはどうやらいろいろ便利な機能があるらしい。

### `functools.lru_cache`でメモ化

`lru_cache`デコレータを使用すると、関数の結果をキャッシュし、
同じ引数で呼び出された場合に計算を省略できるらしい。

```python
from functools import lru_cache

@lru_cache(maxsize=None)
def fibonacci(n):
    if n < 2:
        return n
    return fibonacci(n-1) + fibonacci(n-2)

print(fibonacci(100))  # 非常に高速に計算されます
```

**ちなみに実行したらちゃんと爆速だった。**

### `contextlib.contextmanager`でコンテキストマネージャを簡単に作成

`contextmanager`デコレータを使用すると、
ジェネレータ関数からコンテキストマネージャを簡単に作成できるらしい。

```python
from contextlib import contextmanager

@contextmanager
def tempdir():
    print("一時ディレクトリを作成")
    try:
        yield "temp_dir_path"
    finally:
        print("一時ディレクトリを削除")

with tempdir() as temp_path:
    print(f"一時ディレクトリ {temp_path} で作業中")

# 出力:
# 一時ディレクトリを作成
# 一時ディレクトリ temp_dir_path で作業中
# 一時ディレクトリを削除
```

https://qiita.com/QUANON/items/c5868b6c65f8062f5876

なるほど。

## Pythonの構文

構文にも私の知らない裏技があるらしい。

### アンパック演算子(`*`)
複数の値の代入ができるらしい。

```python
first, *middle, last = [1, 2, 3, 4, 5]
print(first, middle, last)  # 出力: 1 [2, 3, 4] 5
```

### ウォルラス演算子(`:=`)

Python 3.8以降。
代入と評価の同時実行ができるらしい。

```python
if (n := len([1, 2, 3])) > 2:
    print(f"リストの長さは{n}です")
# 出力: リストの長さは3です
```

### `with`文で複数のコンテキストマネージャが使える
まさか複数使えるとは思わないじゃん。

```python
with open('input.txt', 'r') as infile, open('output.txt', 'w') as outfile:
    outfile.write(infile.read().upper())
```

https://qiita.com/kenta1984/items/f3c0904d5d0d2ecb8ca6

## さいごに

Pythonはまだ私のしらない機能で満ちている...
（多分まだまだ初心者なだけ。）

:::note info
**追記**
続編記事を書きました↓
[「Python標準ライブラリのドキュメントでも読むか～」「え、何その裏技」](https://qiita.com/CinnamonSea2073/items/2cae34c3dd7ff86d0950)
:::