Wenn Sie Python verwenden, werden Sie oft feststellen, dass Sie my_list.pop() verwenden, um das letzte Element einer Liste zu entfernen, oder my_dict.pop('key'), um Elemente aus einem Dictionary zu entfernen, und so in vielen verschiedenen Objekten .pop() benutzen.

Es kann so erscheinen, als wäre pop() eine Alleskönner-Instanzmethode, die auf jedes Objekt anwendbar ist. Was verbirgt sich hinter dieser pop()-Methode?


1. Es gibt nicht nur einen 'pop()'



Um es kurz zu machen: list's pop() und dict's pop() sind nur vom Namen her gleich, tatsächlich handelt es sich um völlig verschiedene Methoden.

  • Die list-Klasse definiert ihre eigene pop()-Methode, die für Listen geeignet ist.

  • Die dict-Klasse definiert ebenfalls eine eigene pop()-Methode, die für Dictionaries geeignet ist.

  • Das gilt auch für die set-Klasse.

Es ist ein Merkmal der objektorientierten Programmierung in Python und eine Form der Polymorphie, dass unterschiedliche Objekte Methoden mit demselben Namen haben können. Der Name 'pop' teilt lediglich die konventionelle Bedeutung "ein Element aus einer Datenstruktur herausnehmen (pop) und zurückgeben".


2. Unterschiedliche Funktionsweisen von pop() je Klassen

Nur weil die Namen gleich sind, bedeutet das nicht, dass die Funktionsweise auch gleich ist. Jede Klasse hat pop() entsprechend ihrer Datenstruktur implementiert.

1. list.pop([index])

  • Funktionsweise: Entfernt ein Element an einem bestimmten Index(index) aus der Liste und gibt dieses Element zurück.

  • Merkmal: Wenn kein Index angegeben wird, wird standardmäßig -1 verwendet, was bedeutet, dass dass letzte Element entfernt wird, ähnlich der 'pop'-Operation einer Stapel-Datenstruktur.

  • Beispiel:

my_list = ['a', 'b', 'c']

# Kein Index angegeben (letztes Element 'c' entfernt)
last_item = my_list.pop()
print(f"Zurückgegebener Wert: {last_item}, Verbleibende Liste: {my_list}")
# Ausgabe: Zurückgegebener Wert: c, Verbleibende Liste: ['a', 'b']

# Index 0 angegeben ('a' entfernt)
first_item = my_list.pop(0)
print(f"Zurückgegebener Wert: {first_item}, Verbleibende Liste: {my_list}")
# Ausgabe: Zurückgegebener Wert: a, Verbleibende Liste: ['b']

2. dict.pop(key[, default])

  • Funktionsweise: Entfernt ein Element (Schlüssel-Wert-Paar), das dem bestimmten Schlüssel(key) im Dictionary entspricht, und gibt dessen Wert zurück.

  • Merkmal: Im Gegensatz zu list.pop() muss ein Schlüssel(key) angegeben werden, nicht ein Index. Wenn der Schlüssel nicht existiert und ein default-Wert angegeben ist, wird dieser zurückgegeben, andernfalls tritt ein KeyError auf.

  • Beispiel:

my_dict = {'apple': 1, 'banana': 2}

# Schlüssel 'apple' entfernen
item = my_dict.pop('apple')
print(f"Zurückgegebener Wert: {item}, Verbleibendes Dictionary: {my_dict}")
# Ausgabe: Zurückgegebener Wert: 1, Verbleibendes Dictionary: {'banana': 2}

# Versuch mit nicht vorhandenem Schlüssel ('grape') (default Wert 99 zurückgegeben)
default_item = my_dict.pop('grape', 99)
print(f"Zurückgegebener Wert: {default_item}, Verbleibendes Dictionary: {my_dict}")
# Ausgabe: Zurückgegebener Wert: 99, Verbleibendes Dictionary: {'banana': 2}

3. set.pop()

  • Funktionsweise: Entfernt ein zufälliges Element aus dem Set und gibt dieses Element zurück.

  • Merkmal: Da ein Set eine ungeordnete Datenstruktur ist, kann man nicht vorhersagen, welches Element entfernt wird. pop() erhält keine Parameter.

  • Beispiel:

my_set = {10, 20, 30}

# Zufälliges Element entfernen (nicht vorhersehbar)
item = my_set.pop()
print(f"Zurückgegebener Wert: {item}, Verbleibendes Set: {my_set}")
# Mögliche Ausgabe 1: Zurückgegebener Wert: 10, Verbleibendes Set: {20, 30}
# Mögliche Ausgabe 2: Zurückgegebener Wert: 20, Verbleibendes Set: {10, 30}

3. Warum es so aussieht, als ob es überall passt



Es ist richtig, dass wir denken, als ob pop() eine „Instanzmethode“ ist. Tatsächlich ist pop() eine Methode, die zu jedem Objekt (Instanz) gehört.

Nur weil es wie obj.pop() aussieht, bedeutet das nicht, dass pop() eine globale Funktion ist oder überall definiert ist. Python überprüft dynamisch, ob das Objekt obj ein Attribut (Methode) mit dem Namen method hat, wenn es obj.method() aufruft.

  • my_list ist eine Instanz der list-Klasse, und in der list-Klasse ist pop definiert.

  • my_dict ist eine Instanz der dict-Klasse und auch in der dict-Klasse ist pop definiert.

Deshalb funktionieren sowohl my_list.pop() als auch my_dict.pop().

Was passiert, wenn wir versuchen, pop() auf einem Objekt aufzurufen, das die Methode nicht definiert hat? Wie erwartet tritt ein AttributeError auf. Lassen Sie uns ein Beispiel mit einem Tuple anschauen.

# Ein Tuple (tuple) kann nicht geändert werden, also gibt es keine pop() Methode.
my_tuple = (1, 2, 3)

# AttributeError: 'tuple' object has no attribute 'pop'
my_tuple.pop() 

Eine Infografik zur Illustration der pop()-Methode in Python über drei Datenstrukturen

Zusammenfassung

  1. pop() ist keine globale Funktion oder gemeinsame Methode in Python.

  2. Die list, dict, set usw. sind Methoden, die von jeder Container-Klasse individuell definiert wurden.

  3. Der Grund für die gleiche Namensgebung ist, dass sie die konventionelle Bedeutung des "Entfernens und Zurückgebens von Daten" teilen.

  4. Die Funktionsweise variiert je nach Klasse, sodass list durch einen Index, dict durch einen Schlüssel und set zufällig Elemente entfernt.