diff --git a/homeassistant/helpers/template.py b/homeassistant/helpers/template.py index 7742418c5a7dd..e090e0de2d1e3 100644 --- a/homeassistant/helpers/template.py +++ b/homeassistant/helpers/template.py @@ -2844,6 +2844,7 @@ def __init__( self.globals["iif"] = iif self.globals["bool"] = forgiving_boolean self.globals["version"] = version + self.globals["zip"] = zip self.tests["is_number"] = is_number self.tests["list"] = _is_list self.tests["set"] = _is_set diff --git a/tests/helpers/test_template.py b/tests/helpers/test_template.py index 3123c01f50026..0676ae21ab73b 100644 --- a/tests/helpers/test_template.py +++ b/tests/helpers/test_template.py @@ -6236,3 +6236,48 @@ async def test_template_thread_safety_checks(hass: HomeAssistant) -> None: await hass.async_add_executor_job(template_obj.async_render_to_info) assert template_obj.async_render_to_info().result() == 23 + + +@pytest.mark.parametrize( + ("cola", "colb", "expected"), + [ + ([1, 2], [3, 4], [(1, 3), (2, 4)]), + ([1, 2], [3, 4, 5], [(1, 3), (2, 4)]), + ([1, 2, 3, 4], [3, 4], [(1, 3), (2, 4)]), + ], +) +def test_zip(hass: HomeAssistant, cola, colb, expected) -> None: + """Test zip.""" + assert ( + template.Template("{{ zip(cola, colb) | list }}", hass).async_render( + {"cola": cola, "colb": colb} + ) + == expected + ) + assert ( + template.Template( + "[{% for a, b in zip(cola, colb) %}({{a}}, {{b}}), {% endfor %}]", hass + ).async_render({"cola": cola, "colb": colb}) + == expected + ) + + +@pytest.mark.parametrize( + ("col", "expected"), + [ + ([(1, 3), (2, 4)], [(1, 2), (3, 4)]), + (["ax", "by", "cz"], [("a", "b", "c"), ("x", "y", "z")]), + ], +) +def test_unzip(hass: HomeAssistant, col, expected) -> None: + """Test unzipping using zip.""" + assert ( + template.Template("{{ zip(*col) | list }}", hass).async_render({"col": col}) + == expected + ) + assert ( + template.Template( + "{% set a, b = zip(*col) %}[{{a}}, {{b}}]", hass + ).async_render({"col": col}) + == expected + )