@thomas07: Die Frage ist dann vielleicht was man *nicht* als eine Art Vorstufe zu Datenstrukturen bezeichnen könnte. Wogegen grenzt man das ab? Ob das in einer Datenstruktur endet oder nicht, hängt letztendlich von dem Code ab der das Ergebnis verwendet.
Wobei man hier vielleicht noch mal den Begriff Datenstruktur näher betrachten müsste, denn streng genommen liefert `map()` eine Datenstruktur zurück, allerdings nicht in dem Sinne wie Du den Begriff offenbar verwendest. Das hat snafu ja schon angedeutet. Du meinst damit wie es aussieht Containerdatentypen, also Datentypen die andere Werte speichern und verwalten, wie Listen, Tupel, Wörterbücher, Mengen, und so weiter.
Die Datenstruktur die `map()` liefert besteht aus zwei Elementen: einer Funktion (oder generell einem aufrufbaren Objekt) und einem Iterator. Und darauf ist eine Operation definiert die das jeweils nächste Element aus der Funktion und einem Element aus dem Iterator liefert. Wenn es `map()` nicht gäbe, könnte man sich das als Datentyp der das Iterator-Protokoll implementiert folgendermassen selber schreiben (ungetestet):
Code: Alles auswählen
class Map(object):
def __init__(self, function, *iterables):
self.function = function
self.arguments = zip(*iterables)
def __iter__(self):
return self
def __next__(self):
return self.function(*next(self.arguments))
Wobei hier jetzt wichtig ist, dass `self.arguments` keine Liste mit den Argumenten ist, sondern `zip()` genau wie `map()` einen Iterator liefert, der die Elemente erst bei Bedarf von den übergebenen iterierbaren Objekten abfragt.
Die Implementierung als Klasse habe ich auch nur gewählt, damit man die Datenstruktur, also zwei Werte und eine Operation zum bestimmen des nächsten Elements, explizit sieht. Da Python Generatorausdrücke kennt, könnte man eine `map()`-Funktion sonst auch ganz einfach als Einzeiler definieren (ungetestet):
Code: Alles auswählen
def map_(function, *iterables):
return (function(*arguments) for arguments in zip(*iterables))
Vielleicht noch mal `zip()` als Vedeutlichung als Klasse und alternativ als Generatorfunktion definiert (ungetestet):
Code: Alles auswählen
class Zip(object):
def __init__(self, *iterables):
self.iterables = iterables
def __iter__(self):
return self
def __next__(self):
return tuple(next(it) for it in self.iterables)
# Alternativ als Funktion:
def zip_(*iterables):
while True:
yield tuple(next(it) for it in iterables)