1.

Python len 完全ガイド(文字数 / 要素数 / バイト数との違い / カスタムクラスでの __len__)

編集
この記事の要点
  • len(obj) はオブジェクトの長さ・要素数を返す Python の組み込み関数
  • 文字列なら文字数(コードポイント数)、リスト・タプル・辞書・集合なら要素数
  • マルチバイト文字も 1 文字としてカウント。バイト数を知りたいときは len(s.encode())
  • ジェネレータには使えない(事前に list() 化が必要)
  • 自作クラスで __len__ メソッドを実装すれば len() 対応にできる

len とは

len(obj) は Python の組み込み関数で、オブジェクトの長さ・要素数を返します。文字列・リスト・タプル・辞書・集合・bytes など、長さの概念を持つほとんどのオブジェクトに対して使えます。

基本構文

len(obj)
引数戻り値
長さを持つオブジェクト(__len__ を実装)整数(要素数 / 文字数)

型ごとの使用例

# 文字列 → 文字数
print(len("ABC"))           # 3
print(len("あいう"))         # 3(マルチバイトでも 1 文字 1 カウント)
print(len("hello world"))   # 11

# リスト → 要素数
print(len([1, 2, 3, 4]))    # 4

# タプル
print(len((1, 2)))           # 2

# 辞書 → キーの数
print(len({"a": 1, "b": 2})) # 2

# 集合
print(len({1, 2, 3, 3}))     # 3(重複は 1 つに統合される)

# range
print(len(range(10)))        # 10

# bytes → バイト数
print(len(b"hello"))         # 5
print(len("あ".encode()))    # 3(UTF-8 でのバイト数)

文字数とバイト数の違い

Python 3 では、str に対する len はコードポイント(≒文字)数を返します。バイト数を知りたい場合はエンコードしてから len() を取ります。

s = "あいう"
print(len(s))                      # 3   (文字数)
print(len(s.encode("utf-8")))      # 9   (UTF-8 では 1 文字 3 バイト)
print(len(s.encode("shift_jis")))  # 6   (Shift_JIS では 1 文字 2 バイト)

絵文字や合成文字(結合用文字 + 基底文字など)の場合、見た目の 1 文字が複数のコードポイントになるケースもあります。完全に「人が見た文字単位」で数えたい場合は regex モジュールの \X(書記素クラスタ)が必要です。

長さがない型に対して呼ぶとエラー

# int には長さがない
len(123)
# TypeError: object of type 'int' has no len()

# ジェネレータも長さ未確定
def gen():
    yield 1
    yield 2

len(gen())
# TypeError: object of type 'generator' has no len()

# 必要なら list 化
print(len(list(gen())))  # 2  ※ジェネレータを消費する

計算量

Python の標準コレクションでは、len() はほぼ O(1)(即座に返る)です。要素を数えに走るわけではなく、内部に保持している件数を返すだけだからです。

計算量
str / list / tuple / dict / set / bytesO(1)
rangeO(1)(数式から算出)
ジェネレータ / イテレータ使用不可

典型的なユースケース

# 入力チェック
name = input("名前を入力: ")
if len(name) == 0:
    print("名前は必須です")
elif len(name) > 50:
    print("50文字以内で入力してください")

# 進捗表示
items = [...]
for i, x in enumerate(items, 1):
    print(f"{i}/{len(items)} 処理中: {x}")

# 偶数番目のみ取り出し
data = ["a", "b", "c", "d", "e"]
half = data[: len(data) // 2]

カスタムクラスで len() に対応する

自作クラスでも __len__() メソッドを実装すれば len() で長さを取れます。

class Deck:
    def __init__(self, cards):
        self.cards = cards

    def __len__(self):
        return len(self.cards)

d = Deck(["A", "K", "Q", "J"])
print(len(d))   # 4

# if d: の真偽値判定にも使われる
# __len__ が 0 を返すオブジェクトは Falsy
print(bool(Deck([])))  # False

__len__ を持つオブジェクトは条件式での真偽判定にも使われ、長さ 0 のとき False 扱いになります。if my_list: という慣習的な書き方の根拠です。

NumPy / Pandas など外部ライブラリでの挙動

オブジェクトlen の戻り値
NumPy 配列 np.array([1,2,3])最初の次元のサイズ(多次元なら行数)
Pandas DataFrame行数
Pandas Series要素数
PIL Image使えない(img.size でタプルを取得)

多次元 NumPy 配列で全要素数が欲しいときは arr.size を使います。len(arr) は最初の軸しか見ません。

import numpy as np
a = np.zeros((3, 4))
print(len(a))    # 3      (最初の軸 = 行数)
print(a.size)    # 12     (全要素数)
print(a.shape)   # (3, 4) (形状)

関連の関数・メソッド

用途関数 / メソッド
長さlen(obj)
要素数(ジェネレータ含む)sum(1 for _ in iter)
文字列のバイト数len(s.encode("utf-8"))
書記素単位の文字数regex.findall(r"\X", s) の長さ
最大値・最小値max() / min()

FAQ

Q: ジェネレータの要素数だけ知りたい
A: 完全に消費しないと数えられません。sum(1 for _ in gen) または len(list(gen))。後者はメモリを多く使うので注意。

Q: ファイルの行数を len() で取れる?
A: ファイルオブジェクトは __len__ を持たないため不可。len(f.readlines())sum(1 for _ in f) で代用します。

関連

編集
Post Share
子ページ

子ページはありません

同階層のページ

同階層のページはありません

最近更新/作成されたページ