Page 1 of 1

Strukturpräsentving verschachtelte Karte in Python

Posted: 19 May 2025, 08:34
by Anonymous
Ich schreibe eine Python -Funktion, die von MAP inspiriert ist, die eine Funktion f: Callable [[A], b] und eine willkürlich verschachtelte Struktur von iTerablen (z. B. Listen von Tupeln von Listen von ... von Objekten vom Typ A ) und zurück. Im Idealfall würde es das Diktat [jeder, ein] auch und "homogen" namentuple s unterstützen, indem F nur auf die Werte angewendet und die Tasten unberührt bleiben (nicht

Code: Select all

NamedTuple
s 'Felder sollten alle einen Typ A haben, damit dies funktioniert).
Zum Beispiel:

Code: Select all

>>> f = lambda x: x * 2
>>> input = [([1, 2], [3, 4]), {"foo": 5, "bar": 6}]
>>> nested_map(f, input)
[([2, 4], [6, 8]), {"foo": 10, "bar": 12}]
< /code>
Idealerweise wäre es Typ-Hinweis-freundlich in dem Sinne, dass es einem statischen Checker mitteilen würde, dass das Ausgabeobjekt genau die gleiche Struktur wie die Eingabe hat. Obwohl dies wahrscheinlich viel schwieriger zu erreichen ist. und < /li>
 Es funktioniert bei statischer Typ -Überprüfung nicht gut. < /li>
< /ul>
import inspect
from collections.abc import Iterable
from typing import Any, Callable, Generator, NamedTuple, cast

type MappableIterable[A] = list[A] | tuple[A] | dict[Any, A] | Generator[A]

type NestedIterable[A] = A | MappableIterable["NestedIterable[A]"]

def nested_map[A, B](
f: Callable[[A], B], nested_structure: NestedIterable[A]
) -> NestedIterable[B]:
"""
Takes a nested iterable structure and applies f to all of its nodes,
returning them in the same structure.
"""

structure = type(nested_structure)
match nested_structure:
case dict():
return {
k: nested_map(f, v)
for k, v in nested_structure.items()
}
# NamedTuple
case _ if hasattr(structure, "_fields") and isinstance(
getattr(structure, "_fields"), tuple
):
d = {
k: nested_map(f, v) for
k, v in cast(NamedTuple, nested_structure)._asdict().items()
}
return cast(NestedIterable[B], structure(**d))
case _ if inspect.isgenerator(nested_structure):
return ( nested_map(f, s) for s in nested_structure )
# Have to check str first since it is an Iterable
case str():
return f(nested_structure)
case Iterable():
structure = cast(type[list], structure)
return structure(map(lambda s: nested_map(f, s), nested_structure))
case _:
return f(nested_structure)
Glaubst du, es gibt eine "elegantere" Möglichkeit, dies zu erreichen?