annotate

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Madpuella
User
Beiträge: 11
Registriert: Freitag 28. November 2008, 22:05
Wohnort: Bochum
Kontaktdaten:

Hallo. Ich komme bei der Bearbeitung einer Funktion nicht weiter. Ich habe zwar das Ergebnis der Aufgabe, und habe eigentlich auch eine Idee, wie ich vorgehen soll, aber ich kann diese Idee irgendwie nicht umsetzen und hoffe nun auf Hilfe. Dies ist die Aufgabe:
Schreiben Sie eine Funktion typeannotate(L), die die Elemente e einer hierarchischen Listenstruktur mit ihrem jeweiligen Python-Typ annotiert, d.h., durch Paare (type(e), e):

>>> typeannotate([1,"z",[(8,9),"der mann",0],1+1])

Und dies ist die Lösung:
[(<type 'int'>, 1), (<type 'str'>, 'z'), [(<type 'tuple'>, (8, 9)), (<type 'str'>, 'der mann'), (<type 'int'>, 0)], (<type 'int'>, 2)]

Jetzt muss ich natürlich den Weg finden, wie man zu der Lösung kommt. Ich habe eigentlich nach langem Nachdenken einen Weg gefunden, allerdings hab ich nur in der Theorie eine Ahnung, wie ich vorzugehen habe, aber scheitere an der Praxis. Es ist, als hätte ich ein riesiges Brett vorm Kopf, denn eigentlich erscheint alles recht logisch, aber ich scheine irgendwas zu übersehen, oder bin einfach zu blöd, die Idee umzusetzen. Vielleicht kann mir da ja jemand von euch aus der blöden Situation helfen. Achso, hier meine Idee zu Vorgehensweise:
Zuerst definiere ich eine Funktion typeannotate(L). Da weiss ich schon nicht, ob es reicht einfach def typeannotate(L): zu schreiben. Und dann ist meine Idee folgende:
Wenn das Argument der Funktion eine Liste ist, liefere die Liste der
typeannotate(i) für jedes i in der Liste
Ansonsten liefere das Paar type(x),x

Das sollte also eigentlich recht einfach sein, mit if und else. Allerdings krieg ich es nicht hin, dies so korrekt hinzuschreiben, dass das oben genannte Ergebnis rauskommt. Vielleicht erbarmt sich ja einer von euch und kann mir da auf die Sprüunge helfen...
Lieben Gruß
Benutzeravatar
helduel
User
Beiträge: 300
Registriert: Montag 23. Juli 2007, 14:05
Wohnort: Laupheim

Moin,

such dir ein beliebiges Python-Tutorial aus. Dort werden deine Fragen beantwortet.

Gruß,
Manuel
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Am besten zeigst du den Code, den du schon hast und sagts, was das Problem damit ist.
Offizielles Python-Tutorial (Deutsche Version)

Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Es gibt noch andere aus deinem Kurs/Seminar, die ebenfalls damit Probleme hatten: http://www.python-forum.de/topic-17329.html

Das sollte weiterhelfen ... :wink:
Madpuella
User
Beiträge: 11
Registriert: Freitag 28. November 2008, 22:05
Wohnort: Bochum
Kontaktdaten:

Ich weiss einfach überhaupt nicht, wie ich das formulieren soll. Das ist sehr ärgerlich, denn wenn man schon eine Theorie hat, und diese nicht umsetzen kann, ist es echt ätzend... Deshalb hatte ich gehofft, dass mir jemand hilft, da es ja für euch Experten bestimmt ein Leichtes ist, aus der Idee eine Funktion zu schreiben...
Madpuella
User
Beiträge: 11
Registriert: Freitag 28. November 2008, 22:05
Wohnort: Bochum
Kontaktdaten:

oh, vielen Dank. das hab ich gar nicht gesehen :D
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

verdammt. Ich hab ne Hausaufgabe gelöst >.<
BlackJack

@Madpuella: Du hast es doch schon gelöst -- das was Du da als Idee aufgeschrieben hast, kannst Du fast 1:1 in Quelltext umsetzen und das sieht einfacher aus als der Code in dem anderen Thread, weil der mehr macht, als in der Aufgabe gefragt ist. Also versuch's erst mal ohne den anderen Thread und zeig uns wo Du ganz konkret nicht weiterkommst.
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

Da war auch die Beschreibung falsch :D
Madpuella
User
Beiträge: 11
Registriert: Freitag 28. November 2008, 22:05
Wohnort: Bochum
Kontaktdaten:

Also eigentlich hab ich den Rohbau,und muss nur noch die beiden Rückgabewerte spezifizieren. Also der Rohbau ist ja im Prinzip einfach so:

def typeannotate(l):

if isinstance(l,list):

return LISTEderRekursivenAnwendungVonTypeannotate

else:

return DasPaar

Jetzt krieg ich einfach nicht raus, was ich bei den beiden returns eingeben muss. Bei "DasPaar" einfach nur type(x),x ? Bestimmt nicht, oder? Und Was ich bei dem anderen return eingeben muss weiss ich absolut nicht. Ich seh vermutlich den Wald vor lauter Bäumen nicht und weiss nicht weiter. Ich wäre einfach nur sehr sehr froh, glücklich und erleichtert, wenn mir da jemand die Lösung sagen würde, denn nach vielen Tagen des Probierens verliert man einfach irgendwann die Lust,Motivation und Nerven. Es ist schon blöd, wenn man ein totaler ahnungsloser Anfänger ist, und für andere die Aufgabe sehr einfach ist, aber für einen selber nicht :-( Vielleicht erbarmt sich ja jemand von euch...
Lieben Gruß
Benutzeravatar
str1442
User
Beiträge: 520
Registriert: Samstag 31. Mai 2008, 21:13

Wenn du unbedingt eine Lösung willst sieh in dem anderem Thread nach, auf den Numerix verlinkt hat. Die Lösung von Audax ist aber nicht ganz so trivial.

Ansonsten ist die Struktur schon richtig. Sich jedes einzelne Element anschauen, wenn es eine Liste ist, die Funktion selbst nochmal drauf Anwenden, ansonsten (type(elem), elem) zurückgeben. Einfache Möglichkeit ist eine Generatorfunktion:

Code: Alles auswählen

>>> def deepmap(func, L):
...  for elem in L:
...   if isinstance(elem, list):
...    yield list(deepmap(func, elem))
...   else:
...    yield func(elem)
Da du dieses Konstrukt vermutlich nicht kennst, musst du jedes Element in einer neuen Liste ansammeln und dann diese zurückgeben. Das darfst du jetzt selbst machen.

Das nächste Mal bitte den Thread lesen.
Redprince
User
Beiträge: 128
Registriert: Freitag 22. Oktober 2004, 09:22
Wohnort: Salzgitter
Kontaktdaten:

Madpuella hat geschrieben:Jetzt krieg ich einfach nicht raus, was ich bei den beiden returns eingeben muss. Bei "DasPaar" einfach nur type(x),x ? Bestimmt nicht, oder?
Warum probierst du es nicht einfach aus? Wirst schon nichts kaputtmachen.. :roll:
str1442 hat geschrieben:Einfache Möglichkeit ist eine Generatorfunktion.
Ist ein Generator an dieser Stelle pythonisch, oder einfach nur umständlich? Was spricht gegen eine simple rekursive Funktion?
I am not part of the allesburner. I am the [url=http://allesburner.de]allesburner[/url].
Benutzeravatar
str1442
User
Beiträge: 520
Registriert: Samstag 31. Mai 2008, 21:13

Der Generator ist doch rekursiv. Ich sehe nicht was an den 5 Zeilen umständlich sein soll. Abgesehen davon, daß die Funktion an sich unpythonisch ist wegen der expliziten Typprüfung auf einen sehr integralen Datentyp.
Redprince
User
Beiträge: 128
Registriert: Freitag 22. Oktober 2004, 09:22
Wohnort: Salzgitter
Kontaktdaten:

Ich verstehe nicht, weshalb man einen Generator schreibt, der zur Lösung des Problems entsprechend aufgerufen werden muss; und was gegen eine normale Funktion spricht, die einfach das Ergebnis liefert. Daher die Frage nach dem Stil oder dem pythonischen ;)

Code: Alles auswählen

In [1]: def typeannotate(elements):
   ...:     res = []
   ...:     for element in elements:
   ...:         if isinstance(element, list):
   ...:             res.append(typeannotate(element))
   ...:         else:
   ...:             res.append((type(element), element))
   ...:     return res
War jetzt mein Ansatz ohne Generator.. Klärt mich auf!
I am not part of the allesburner. I am the [url=http://allesburner.de]allesburner[/url].
Benutzeravatar
BlackVivi
User
Beiträge: 762
Registriert: Samstag 9. Dezember 2006, 14:29
Kontaktdaten:

Redprince hat geschrieben:Klärt mich auf!
Weil die Lösungen sich vom Ergebnis her kaum bis gar nicht unterscheidene, die Lösung mit dem Generator aber intuitiv logischer und vor allem schneller von'r Hand geschrieben ist. Wenn du'ne Liste zurückgeben musst ist'n Generator cool... Er vermeidet eine temporäre Variable =D
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Außerdem sind Generatoren lazy. Wie Python-Programmierer. Also quasi ein "perfect match".
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
BlackJack

@BlackVivi: Wie bitte? Intuitiv logischer? Schneller von der Hand geschrieben? Also ich finde die Generatorlösung sieht komplizierter aus als das hier und hat auch mehr Code:

Code: Alles auswählen

def type_annotate(obj):
    if isinstance(obj, list):
        return map(type_annotate, obj)
    else:
        return (type(obj), obj)
Ausserdem hat so eine rekursiv lazy Variante dann auch Probleme beim Anzeigen, das erfordert dann nämlich auch wieder ein relativ komplizierten Code statt eines einfachen ``print``. Immer dran denken wie die Ausgabe aussehen soll.
Benutzeravatar
BlackVivi
User
Beiträge: 762
Registriert: Samstag 9. Dezember 2006, 14:29
Kontaktdaten:

BlackJack hat geschrieben:@BlackVivi: Wie bitte? Intuitiv logischer?
Für _mich_ schon. Über viele Sachen lassen sich streiten, aber der Generator für diese Funktion ist für mich mal leichter... Und für andere bestimmt auch.
BlackJack hat geschrieben:Ausserdem hat so eine rekursiv lazy Variante dann auch Probleme beim Anzeigen, das erfordert dann nämlich auch wieder ein relativ komplizierten Code statt eines einfachen ``print``. Immer dran denken wie die Ausgabe aussehen soll.
Das ist wiederum ein Argument... Wobei man allgemein für einen sinnvollen Einsatz für die Datenstruktur sich etwas ausdenken muss, finde ich.
Benutzeravatar
str1442
User
Beiträge: 520
Registriert: Samstag 31. Mai 2008, 21:13

Mehrere Dinge:

1. So eine typeannotate Funktion ist höchstwahrscheinlich nicht für den Gebrauch innerhalb von Programmen gedacht, sondern höchstens für den Programmierer. Abgesehen davon daß die Aufgabe sowieso eine Hausaufgabe war.

Aus dieser Sicht disqualifiziert sich ein Generator für so ein Problem. Dennoch ist es als Generator ebenfalls leicht zu schreiben und es kam mir intuitiv in den Sinn. Zumal Generatoren zu viel mehr nutzbar sind als "nur" Iterables zu bilden.

2. Der Grund, warum ich es schlussendlich als Generator hingeschrieben habe, war, daß man so die Grundstruktur, die Madpuella ja richtig erkannt hat, mehr oder weniger "rein" dargestellt bekommt, und zugleich der Teil "schreibe das Ganze nun als Funktion mit einem Returnpoint und einer Liste, an die Elemente angehängt werden" und "schreibe eine Funktion typeannote, die deepmap() nutzt" als Übung übrig bleiben, was sich ja jetzt erledigt hat.

Hier ist übringens noch eine Variante:

Code: Alles auswählen

>>> def deepmap(func, ls):
...  return [func(elem) if not isinstance(elem, list) else deepmap(func, elem) for elem in ls]
... 
:P
Antworten