diff --git a/pandas/core/indexes/multi.py b/pandas/core/indexes/multi.py index dc48cd1ed958e..f8023100571e2 100644 --- a/pandas/core/indexes/multi.py +++ b/pandas/core/indexes/multi.py @@ -9,6 +9,7 @@ Sequence, ) from functools import wraps +from itertools import zip_longest from sys import getsizeof from typing import ( TYPE_CHECKING, @@ -591,7 +592,7 @@ def from_tuples( elif isinstance(tuples, list): arrays = list(lib.to_object_array_tuples(tuples).T) else: - arrs = zip(*tuples) + arrs = zip_longest(*tuples) arrays = cast(list[Sequence[Hashable]], arrs) return cls.from_arrays(arrays, sortorder=sortorder, names=names) diff --git a/pandas/tests/indexes/multi/test_constructors.py b/pandas/tests/indexes/multi/test_constructors.py index b2867d4ac8e68..53bd73c42c1a3 100644 --- a/pandas/tests/indexes/multi/test_constructors.py +++ b/pandas/tests/indexes/multi/test_constructors.py @@ -409,6 +409,14 @@ def test_from_tuples_with_tuple_label(): result = pd.DataFrame([2, 3], columns=["c"], index=idx) tm.assert_frame_equal(expected, result) +@pytest.mark.parametrize("keys, expected", ( + ((("l1",), ("l1","l2")), (("l1", np.nan), ("l1","l2"))), + ((("l1","l2",), ("l1",)), (("l1","l2"), ("l1", np.nan))), +)) +def test_from_tuples_with_various_tuple_lengths(keys, expected): + # Issue 60695 + idx = MultiIndex.from_tuples(keys) + assert tuple(idx) == expected # ---------------------------------------------------------------------------- # from_product