Guten Morgen BlackJack,
ja, das ist auch eine gute Idee und die Benennung ist auch mit Zahl sinnvoller.
Viele Grüße
Thomas
Multiparameter an Funktion über Input() übergeben ?
Oder man nutzt gleich eine List Comprehension:BlackJack hat geschrieben:Oder man zieht gleich ein bisschem mehr in einen Ausruck zusammen und gibt der Liste mit den Zahlen den Namen `zahlen` statt den für eine Zeichenkette zu verwenden und die Zahlen an den sehr allgemeinen Namen `liste` zu binden:Code: Alles auswählen
zahlen = list(map(float, input('Werte eingeben! ').split(',')))
Code: Alles auswählen
zahlen = [float(zahl) for zahl in input('Werte eingeben: ').split(',')]
Hallo zusammen,
wenn ich so genau hinschaue, stellt sich mir die Frage: Warum hatt map() keinen direkt verwendbaren Rückgabewert und muss erst mit list, tuple usw. konvertiert werden, zumal man ja ihr eine Sequenz übergibt.
Ich würde von map() einen Rückgabetyp wie der Typ der übergebenen Sequenz.
Was meint Ihr dazu?
Viele Grüße
Thomas
wenn ich so genau hinschaue, stellt sich mir die Frage: Warum hatt map() keinen direkt verwendbaren Rückgabewert und muss erst mit list, tuple usw. konvertiert werden, zumal man ja ihr eine Sequenz übergibt.
Ich würde von map() einen Rückgabetyp wie der Typ der übergebenen Sequenz.
Was meint Ihr dazu?
Viele Grüße
Thomas
Man kann `map()` durchaus direkt verwenden. Zum Beispiel so:
Der Grund für das Design von `map()` (bezogen auf Python 3), ist dass man direkt über das Ergebnis iterieren kann, ohne dass aus den einelnen Elementen erst noch in eine Datenstruktur gebaut wird (also z.B. eine Liste), die nach dem Iterieren eh wieder weggeworfen würde. Wenn man es mit sehr vielen Elementen zu tun hat, dann kann das durchaus ein spürbarer Performancegewinn sein. Wenn man hingegen tatsächlich eine Liste benötigt, dann muss man dies explizit angeben, oder eben - wie gezeigt - `map()` komplett weglassen und stattdessen eine List Comprehension benutzen.
Code: Alles auswählen
>>> print(*map(float, range(3)), sep='\n')
0.0
1.0
2.0
@thomas07: `map()` hat einen verwendbaren Rückgabewert, nur halt nicht das was Du erwartet hast. Wenn ich schaue wie oft ich in Python 2 `map()` verwende und wie oft `itertools.imap()` dann ist es IMHO schon ein guter Schritt bei Python 3 gewesen `map()` durch etwas zu ersetzen was sich wie `itertools.imap()` verhält. Oft ist das Ergebnis ja nur ein Zwischenschritt.
Hallo zusammen,
Das leuchtet mir jetzt ein, aber eine Sache noch: das Ergebnis von map ist zwar keine List, Tuple, Dict oder Set, aber dennoch liegen die Daten ja in einer bestimmten Struktur vor. Deshalb meine Frage: Kann man das Ergebnis von map nicht als eine Datenstruktur betrachten? Oder haben Datenstrukturen besondere Eigenschaften, die dem map-Ergebnis fehlen?
Viele Grüße
Thomas
In der Tat, das mit * kannte ich bisher nicht. Das macht natürlich die Sache etwas einfacher - jedenfalls von der Code-Länge her.snafu hat geschrieben:Man kann `map()` durchaus direkt verwenden. [...]
Gut, wieder was neues gelernt und den Hintergrund gleich dazu .snafu hat geschrieben:Der Grund für das Design von `map()` (bezogen auf Python 3), ist dass man direkt über das Ergebnis iterieren kann, ohne dass aus den einelnen Elementen erst noch in eine Datenstruktur gebaut wird (also z.B. eine Liste), die nach dem Iterieren eh wieder weggeworfen würde. Wenn man es mit sehr vielen Elementen zu tun hat, dann kann das durchaus ein spürbarer Performancegewinn sein. Wenn man hingegen tatsächlich eine Liste benötigt, dann muss man dies explizit angeben, oder eben - wie gezeigt - `map()` komplett weglassen und stattdessen eine List Comprehension benutzen.
Das leuchtet mir jetzt ein, aber eine Sache noch: das Ergebnis von map ist zwar keine List, Tuple, Dict oder Set, aber dennoch liegen die Daten ja in einer bestimmten Struktur vor. Deshalb meine Frage: Kann man das Ergebnis von map nicht als eine Datenstruktur betrachten? Oder haben Datenstrukturen besondere Eigenschaften, die dem map-Ergebnis fehlen?
Ja, da habe ich mich etwas undeutlich ausgedrückt. Da ich versucht hatte, den Rückgabewert von map direkt über print auszugeben und es nicht geklappt hatte, dachte ich, dass die map Funktion keinen direkt verwendbaren Wert liefert.BlackJack hat geschrieben:@thomas07: `map()` hat einen verwendbaren Rückgabewert, nur halt nicht das was Du erwartet hast.
Ich habe mit der Version 2 nur sehr wenig gearbeitet und kenne z. B. itertools nicht (aber werde es gleich nachholen), aber mit der 3er Version möchte ich mich intensiver beschäftigen und danke Euch sehr für Eure Unterstützung, denn manchmal komme ich mit der Dokumentation und Probieren nicht weiter.BlackJack hat geschrieben:Wenn ich schaue wie oft ich in Python 2 `map()` verwende und wie oft `itertools.imap()` dann ist es IMHO schon ein guter Schritt bei Python 3 gewesen `map()` durch etwas zu ersetzen was sich wie `itertools.imap()` verhält. Oft ist das Ergebnis ja nur ein Zwischenschritt.
Viele Grüße
Thomas
Das Ergebnis von `map()` in Python 3.x ist im Grunde ja nur ein "stinknormaler" Iterator. Ich würde sagen, das ist keine Datenstruktur oder höchstens ein Randfall. Denn bei Datenstrukturen erwartet man als Anwender, dass man eine für den Datentyp typische Funktionalität für Zugriff und Modifikation der enthaltenen Daten erhält (bei Listen z.B. "gib Element an Index 0", "füge Element 'x' hinzu", usw). Bei Iteratoren hingegen kann man im Regelfall immer nur das nächste Element, was an der Reihe ist, erhalten. Außerdem teilt einem der Iterator mit, wann keine für die Ausgabe bestimmten Elemente mehr übrig sind. Und das war's dann auch schon. Gut, das ist natürlich immer noch ein allgemein bekannter Mechanismus - eine Datenstruktur ist es aber eher nicht. Aber wie gesagt: Hier kann man vielleicht auch anderer Meinung sein, sofern man "Datenstruktur" etwas anders definieren möchte.thomas07 hat geschrieben:aber eine Sache noch: das Ergebnis von map ist zwar keine List, Tuple, Dict oder Set, aber dennoch liegen die Daten ja in einer bestimmten Struktur vor. Deshalb meine Frage: Kann man das Ergebnis von map nicht als eine Datenstruktur betrachten? Oder haben Datenstrukturen besondere Eigenschaften, die dem map-Ergebnis fehlen?
@thomas07: Beim Ergebnis von `map()` (in Python 3) liegen die Daten ja gerade *nicht* tatsächlich schon vor, wie zum Beispiel in einer Liste wo jedes Element der Liste zum gleichen Zeitpunkt existiert und alle zusammen Speicherplatz belegen. `map()` liefert ein Objekt das jedes einzelne Element auf Anfrage der Reihe nach erstellt/berechnet. Das heisst solange man sich die Elemente nicht in irgendeiner Datenstruktur merkt, müssen die Elemente nur so lange existieren und Speicher belegen wie man jedes einzelne braucht und verarbeitet. Da die Elemente nur auf Anfrage berechnet werden, kann man auch aufhören bevor das oder die iterierbaren Objekte die an `map()` übergeben wurden, alle verarbeitet wurden und spart damit womöglich Rechenarbeit. Und aus dem gleichen Grund kann man `map()` auch auf iterierbare Objekte anwenden die *unendlich* viele Werte liefern und somit eine Liste mit den Ergebnissen gar nicht in den Arbeitsspeicher passt, egal wie viel man davon hat.
@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):
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):
Vielleicht noch mal `zip()` als Vedeutlichung als Klasse und alternativ als Generatorfunktion definiert (ungetestet):
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))
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))
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)