Dictionary- Konstruktor

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.
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

rolgal_reloaded hat geschrieben:@birkenfeld

Eigentlich schon klar, aber in BlackJacks Beispiel bekomme ich dasselbe heraus, wie in meinem Beispiel mit einer Listcomprehension. Also eben sehr wohl Listen!

Deshalb bin ich verwirrt.
Nein, wenn du "list(x.iterkeys)", oder sonnt ein Objekt mit ner Generator Methode, mit list, tumple, etc benutzt, dann iterieren die selber darüber, also ruft next ;)
Beispiel
tuple(x.iterkeys()), list(x.iterkeys()), for i in x.iterkeys():

lg

EDIT: Wenn du "selber" iterieren willst geht das so:
y = x.iteritems()
y.next()
y.next()
etc...
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Code: Alles auswählen

x = {"foo": "bar", "blub": "spam"}
print x
y = x.iteritems()
print y.next()
print y.next()
print y.next()
output:

Code: Alles auswählen

{'foo': 'bar', 'blub': 'spam'}
('foo', 'bar')
('blub', 'spam')
Traceback (most recent call last):
  [...]
    print y.next()
StopIteration
Es wird also bis StopIteration iteriert. Und nichts anderes machen list(), etc auch :)
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

EDIT: Ach so: das dran eine liste rauskommt ist normal, weil list() alle Elemente die es vom Generator kriegt dort reinfügt.
rolgal_reloaded
User
Beiträge: 312
Registriert: Dienstag 24. Oktober 2006, 19:31

XtraNine hat geschrieben:EDIT: Ach so: das dran eine liste rauskommt ist normal, weil list() alle Elemente die es vom Generator kriegt dort reinfügt.
Danke, war etwas wirr das Ganze, aber ich glaube ich habs:
Durch die Listcomprehension wird list() aufgerufen, welches alle Elemente, die es vom Generator bekommt......,richtig?

edit: Da habe ich vor lauter Lösungen wieder mal alles durcheinander geworfen, naja, eigenltich egal, der Thread ist so oder so gelöst.

LG

rolgal_reloaded
Zuletzt geändert von rolgal_reloaded am Sonntag 3. Dezember 2006, 14:48, insgesamt 1-mal geändert.
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Nein, list() ansich wird nicht aufgerufen. Die List comprehension gleicht einer for-Schleife:

Code: Alles auswählen

l = [f(x) for x in y]
ist das gleiche wie

Code: Alles auswählen

l = []
for x in y:
    l.append(f(x))
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Naja wie das genau intern abläuft weiß ich nicht. Die Antwort überlasse ich den Profis hier. Eins steht auf jeden Fall fest, das ``[]``, ``()``, ``list()``, ``tuple()`` genauso in der Lage sind zu iterieren wie z.B. ``for``.
Durch die Listcomprehension wird list() aufgerufen, welches alle Elemente, die es vom Generator bekommt......,richtig?
Ne nicht ganz: Für ``[]`` wird der Opcode ``BUILD_LIST`` aufgerufen. ``list()`` dagegen wird erste in den Globals aufgelöst und ruft dann den Opcode auf (Richtig, birkenfeld?). Die sorgen nun dafür das bei einem Generator die ``.next()``-Methode aufgerufen wird und gibt bei jeder Iteration ein Element wider, bis ein ``StopIteration`` ausgelöst wird und das iterieren beendet wird.

Aber wie gesagt, wie das ganz genau intern abläuft weiß ich nicht.

EDIT: Hier noch ein Thread wo Birkenfeld den unterschied zwischen {} und dict{} erklärt hat, was sich auch auf list() übertragen lässt: http://www.python-forum.de/topic-8119.h ... hlight=24h

EDIT2: Wider zu spät.
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

XtraNine hat geschrieben:``list()`` dagegen wird erste in den Globals aufgelöst und ruft dann den Opcode auf (Richtig, birkenfeld?).
Nicht ganz: da brauchts keinen Opcode mehr, weil der Typ "list" ja direkt in C implementiert ist und daher nur die entsprechende C-API-Funktion aufruft.
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
rolgal_reloaded
User
Beiträge: 312
Registriert: Dienstag 24. Oktober 2006, 19:31

birkenfeld hat geschrieben:Nein, list() ansich wird nicht aufgerufen. Die List comprehension gleicht einer for-Schleife:

Code: Alles auswählen

l = [f(x) for x in y]
ist das gleiche wie

Code: Alles auswählen

l = []
for x in y:
    l.append(f(x))
Ist mir klar, dann wird halt was äquvivalentes wie list() aufgerufen. Es wird in jedem Fall eine Liste erzeugt, die bewirt, dass sich iterkeys() usw. sich so verhält wie oben beschrieben. - ?

LG

rolgal_reloaded
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

birkenfeld hat geschrieben:
XtraNine hat geschrieben:``list()`` dagegen wird erste in den Globals aufgelöst und ruft dann den Opcode auf (Richtig, birkenfeld?).
Nicht ganz: da brauchts keinen Opcode mehr, weil der Typ "list" ja direkt in C implementiert ist und daher nur die entsprechende C-API-Funktion aufruft.
Ah, ok, danke dir :) Damit solte das Mysterium geklärt sein.

BTW: @all: dis.dis(...) ist Super :D ^^

lg
Zuletzt geändert von sape am Samstag 2. Dezember 2006, 23:56, insgesamt 1-mal geändert.
rolgal_reloaded
User
Beiträge: 312
Registriert: Dienstag 24. Oktober 2006, 19:31

Inzwischen frage ich mich, ob es bei aller Eleganz die der Code von BlackJack hat, stilistisch nicht etwas seltsam ist eine Methode der Elternklasse mittels einer anderen Methode der Elternklasse zu überschreiben.

Das ist mir jetzt nur mal so durch den Kopf gegangen.

Ich habe aber nicht wirklich die Erfahrung und das KnowHow das wirklich zu beurteilen.

Vielleicht gibts noch andere Meinungen dazu.

LG

rolgal_reloaded
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Puh, das weiß ich nicht. Das kann ich ncoh nicht beurteilen weil mir die entsprechende Erfahrung fehlt.

Aber mal ganz im vertrauen: BlackJacks Code haben zu 99% Hand und Fuss ;) Der weis __GANZ__ genau was er da Treibt :D

lg
rolgal_reloaded
User
Beiträge: 312
Registriert: Dienstag 24. Oktober 2006, 19:31

XtraNine hat geschrieben:Puh, das weiß ich nicht. Das kann ich ncoh nicht beurteilen weil mir die entsprechende Erfahrung fehlt.

Aber mal ganz im vertrauen: BlackJacks Code haben zu 99% Hand und Fuss ;) Der weis __GANZ__ genau was er da Treibt :D

lg
8) :wink:
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

rolgal_reloaded hat geschrieben:Inzwischen frage ich mich, ob es bei aller Eleganz die der Code von BlackJack hat, stilistisch nicht etwas seltsam ist eine Methode der Elternklasse mittels einer anderen Methode der Elternklasse zu überschreiben.
Wieso? In vielen Fällen ruft man in der überschriebenen Methode die entsprechende Methode der Elternklasse auf. In diesem Fall ist es aber sinnvoller, da effizienter, eine andere Methode der Elternklasse zu verwenden.
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

rolgal_reloaded hat geschrieben:Inzwischen frage ich mich, ob es bei aller Eleganz die der Code von BlackJack hat, stilistisch nicht etwas seltsam ist eine Methode der Elternklasse mittels einer anderen Methode der Elternklasse zu überschreiben.
Warum sollte sowas seltsam sein? Eine Kindklasse erweitert die Elternklasse ja und kann dabei doch durchaus auf Dinge zurückgreifen die die Elternklasse schon bietet - warum das Rad noch einmal erfinden? Dass eine von dict abgeleitete Klasse die Funktion iteritems() bietet, davon ist auszugehen - es wäre seltsam Dinge in der Kindklasse zu löschen.
Stellt euch vor, die Elternklasse macht etwas sehr flexibel und für den Benutzer dieser Klasse unpraktisch. Gehen wir mal vom Beispiel einer Klasse zur Versionsverwaltung aus:

Code: Alles auswählen

class HighlyFlexibleVCS(object):
   def update(self):
      # Code um den Checkout zu aktualisieren
      pass   
   def pull(self):
      # Code um den aktuellen Code aus einem entfernten Repository zu holen
      pass
   def commit(self):
      # Code um etwas einzuchecken
      pass
   def push(self):
      # Code um den aktualisierten Code an ein entferntes Repository zu schicken
      pass

class SimplifiedVCS(HighlyFlexibleVCS):
   def download(self):
      self.pull()
      self.push()
   def upload(self):
      self.commit()
      self.push()
Nun stellt die Klasse SimplifiedVCS einfach nur ein vereinfachtes Interface zu seiner Elternklasse dar und nutzt dessen Funktionen. Ok, das Beispiel ist zugegebenermaßen ziemlich konstruiert ;)
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
BlackJack

rolgal_reloaded hat geschrieben:Wenn man damit im Interpreter rumspielt bekommt man aber folgendes:

Code: Alles auswählen

>>> d = {"Italien":"Rom","Spanien":"Madrid","Belgien":"Brüssel","Frankreich":"Paris"}
>>> d.items()
[('Spanien', 'Madrid'), ('Italien', 'Rom'), ('Frankreich', 'Paris'), ('Belgien', 'Br\xfcssel')]
>>> d.keys()
['Spanien', 'Italien', 'Frankreich', 'Belgien']
>>> d.iterkeys()
<dictionary-keyiterator object at 0x01553D60>
Ich meine: wenn ich mit iterkeys() in deinem Code der Klasse MyDict dasselbe bekomme wie mit meiner Listcomprehension

Code: Alles auswählen

    def keys(self):
        return sorted([key for key in self]) 
, dann müsste ich doch in der oben gezeigten interaktiven Sitzung auch mehr rausbekommen als einen schönen Gruß übern Interpreter
Die Liste oder der Iterator werden als Argument an `sorted()` übergeben. Wichtig ist was *diese* Funktion zurückgibt. Nämlich eine sortierte Liste mit den Elementen des "iterable", das als Argument übergeben wurde.

Code: Alles auswählen

In [1]: d = {"Italien":"Rom","Spanien":"Madrid","Belgien":"Brüssel","Frankreich":"Paris"}

In [2]: d.iterkeys()
Out[2]: <dictionary-keyiterator object at 0xb7951300>

In [3]: sorted(d.iterkeys())
Out[3]: ['Belgien', 'Frankreich', 'Italien', 'Spanien']
rolgal_reloaded
User
Beiträge: 312
Registriert: Dienstag 24. Oktober 2006, 19:31

@Leonidas, @Blackjack,

wunderbar eure Antworten, leuchtet mir alles ein. :D

LG

rolgal_reloaded
Antworten