HOWTO · Python

Python で複数のリストとタプルからタプルのリストを作成する

Python で複数のリストとタプルからタプルのリストを作成する方法

このページの内容

list(zip(values_a, values_b, ...)) を使うと、同じ位置の値を組み合わせ、結果をタプルのリストとして具体化できます。組み込み関数 zip() はリスト、タプル、その他のイテラブルを受け取るため、Python で対応する値を組み合わせる分かりやすい方法です。

この記事では Python 3.14.7 を使用し、同じ長さの入力、異なる長さの既定の動作、厳密な検証、入力が長い場合にすべての行を残す方法を説明します。

zip() が返すもの

zip() の各要素は、各入力から一つの値を含むタプルです。zip オブジェクトは遅延評価され、反復時にタプルを生成します。印刷、インデックス参照、再利用が必要なら list() で具体化します。

入力にはリストとタプルを混在させられます。組み合わせは位置に基づき、タプルの長さは入力イテラブルの数になります。

同じ長さの入力からタプルのリストを作る

次の例では数値のリストと文字のタプルを組み合わせます。list(zip(...)) は遅延イテレーターを消費してタプルのリストを返します。

values = list(zip([1, 2, 3], ("a", "b", "c")))
print(values)

出力:

[(1, 'a'), (2, 'b'), (3, 'c')]

同じ長さの入力では各位置に一つのタプルができます。第三者パッケージは不要で、出力リストのメモリはタプル数に比例します。一度だけ反復するなら遅延 zip を使います。

長さの異なる入力を扱う

既定では zip() は最短の入力が尽きると停止します。余分な値を無視するには便利ですが、同じ長さが必要な場合は不足データを隠すことがあります。等長が不変条件なら strict=True を使い、長さが違えば Python は ValueError を発生させます。

try:
    list(zip([1, 2, 3], ("a", "b"), strict=True))
except ValueError as error:
    print(type(error).__name__, str(error))

出力:

ValueError zip() argument 2 is shorter than argument 1

strict=True は Python 3.10 以降で利用できます。整列を保つレコードに適しており、ValueError を処理するか入力を検証します。

itertools.zip_longest() ですべての入力行を残す

最長入力の位置も必要なら既定の zip() ではなく itertools.zip_longest() を使います。不足位置は fillvalue がなければ None で埋められます。実値と区別できるセンチネルを選びます。

たとえば list(itertools.zip_longest(first, second, fillvalue="missing")) は全位置を残し、不足値を示します。最短入力で切り詰めて行を失う場合に適した動作です。

明示的な制御が必要な場合に手動でリストを作る

手動のインデックス方式は、入力を list または tuple として検証する場合や独自規則を置く場合に便利です。実行可能なフォールバック convert = lambda *args: [] if not all(isinstance(value, (list, tuple)) for value in args) else [tuple(value[index] for value in args) for index in range(min((len(value) for value in args), default=0))] は検証を保ち、最短入力で停止します。例の四つの値に対して [(1.1, 'H', True, 100), (2.2, 'E', False, 200), (3.3, 'L', False, 300)] を返します。

この関数は list でも tuple でもない型を拒否し、最短入力で停止します。最短長を m、入力数を n とすると、時間と結果用の空間は O(m * n) です。

適切な方法を選ぶ

通常の位置ベースの組み合わせには list(zip(...))、一度の反復には遅延 zip() を使います。長さの違いが不正データなら strict=True、行を落とせないなら明示的な補充値付き itertools.zip_longest() を使います。手動方式は独自規則のフォールバックです。