Built-in Funktionen in Python – Teil 1

Fast jeder, der eine Programmiersprache lernt (z.B. Python), stellt sich am Anfang sicherlich die Frage: „Wie kann man erwarten, dass ich das alles jemals weiß und beherrsche.“

Die Frage geht in der Regel in die Richtung:

  • Python hat so viele Funktionen, wie kann man sich die alle am besten merken? 
  • Wie lernt man am besten die Funktionen, die man im Alltag braucht, wie z.B. enumerate und range? 
  • Woher kennt man all die Möglichkeiten, Probleme in Python zu lösen? Lernt man sie auswendig? 

Es gibt Dutzende von eingebauten Funktionen und Klassen, Hunderte von Werkzeugen, die in der Python-Standardbibliothek gebündelt sind, und Tausende von Bibliotheken von Drittanbietern auf PyPI. Es ist unmöglich, dass sich jemand all diese Dinge merken kann.

Man sollte sein Wissen zunächst sortieren:

  • Dinge, die man auswendig lernen sollte, damit man sie gut kennt 
  • Dinge, die man wissen sollte, damit man sie später effektiver nachschlagen kann 
  • Dinge, mit denen man sich überhaupt nicht beschäftigen sollte, bis man sie eines Tages braucht 

Dieser Artikel geht mit diesem Ansatz durch die Seite „built-in functions“ in der Python-Dokumentation.

Da dieses Thema sehr umfangreich ist, wird es in mehrere Artikel aufgeteilt, so dass man mit entsprechendem Wissen und Erfahrung gleich zu einem bestimmten Beitrag vorspringen kann.

Welche Built-Ins sollte man kennen?

Vermutlich werden die meisten Python-Entwickler nur etwa 30 eingebaute Funktionen benötigen. Aber welche dies sind, hängt immer davon ab, was man tatsächlich mit Python macht.
Es wird hier einen Blick auf alle eingebauten Funktionen (built-in functions) von Python aus der Vogelperspektive geben.
Man kann diese built-in Funktionen in fünf Kategorien zu unterteilen:

  • Allgemein bekannte Built-Ins: Die meisten neueren Pythonisten lernen diese Built-Ins aus der Not heraus ziemlich schnell kennen. 
  • Von neuen Pythonisten übersehen: Diese Funktionen sind nützlich, aber man kann sie leicht übersehen, wenn man noch nicht so lange mit Python vertraut ist. 
  • Später lernen: Diese Build-Ins sind im Allgemeinen nützlich, aber man wird sie finden, wenn man sie braucht. 
  • Vielleicht lernt man diese irgendwann: Sie können nützlich sein, aber nur unter bestimmten Umständen. 
  • Man braucht sie wahrscheinlich nicht: Man wird sie wahrscheinlich nicht brauchen, es sei denn, man macht etwas ziemlich Spezielles.

Die built-in Funktionen in den Kategorien 1 und 2 sind die wesentlichen Built-Ins, die fast alle Python-Programmierer irgendwann lernen sollten. Die Funktionen in den Kategorien 3 und 4 sind die spezialisierten built-in Funktionen, die oft sehr nützlich sind, aber der Bedarf an ihnen hängt von der Verwendung von Python ab. Und Kategorie 5 sind geheimnisvolle Build-Ins, die sehr nützlich sein können, wenn man sie braucht, die aber viele Python-Programmierer wahrscheinlich nie brauchen werden.

Hinweis für pedantische Pythonistas: Hier werden alle diese Build-Ins als Funktionen bezeichnen, auch wenn einige von ihnen eigentlich keine Funktionen sind.

Die allgemein bekannten built-in Funktionen (die auch Python-Neulinge wahrscheinlich schon kennen):

  1. print
  2. len
  3. str
  4. int
  5. float
  6. list
  7. tuple
  8. dict
  9. set
  10. range

Die built-in Funktionen, die von neueren Python-Programmierern oft übersehen werden:

  1. sum
  2. enumerate
  3. zip
  4. bool
  5. reversed
  6. sorted
  7. min
  8. max
  9. any
  10. all

Es gibt noch 5 häufig übersehene Build-Ins, die im Rahmen der Fehlersuche und des Debugging nützlich sein können:

  1. dir
  2. vars
  3. breakpoint
  4. type
  5. help

Zusätzlich zu den oben genannten 25 Funktionen werden in Folgeartikeln auch die anderen eingebauten Funktionen in den Abschnitten „Später lernen“, „Vielleicht irgendwann lernen“ und „Wahrscheinlich braucht man diese nicht“ kurz betrachtet.

Die 10 allgemein bekannten built-in Funktionen

Wenn man bereits Python-Code geschrieben hat, dann sind diese eingebauten Funktionen wahrscheinlich schon bekannt.

print

Die Funktion print dürfte man kennen, denn die Implementierung von „hello world“ erfordert print.
Die verschiedenen Schlüsselwortargumente (keyword arguments), die print akzeptiert, sind aber vielleicht nicht bekannt:

>>> words = ["Welcome", "to", "Python"]
>>> print(words)
['Welcome', 'to', 'Python']
>>> print(*words, end="!\n")
Welcome to Python!
>>> print(*words, sep="\n")
Welcome
to
Python

len

In Python schreibt man nicht my_list.length() oder my_string.length; stattdessen verwendet man merkwürdigerweise (zumindest für Python-Neulinge) len(my_list) und len(my_string).

>>> words = ["Welcome", "to", "Python"]
>>> len(words)
3

Unabhängig davon, ob man diese Operator-ähnliche len-Funktion mag, man muss sich an sie gewöhnen.

str

Im Gegensatz zu vielen anderen Programmiersprachen gibt es in Python keinen Typenzwang, so dass man in Python keine Zeichenketten und Zahlen miteinander verknüpfen kann.

>>> version = 3
>>> "Python " + version
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can only concatenate str (not "int") to str

Python weigert sich, diese 3 in eine Zeichenkette umzuwandeln, also muss man es manuell selbst tun, indem man die eingebaute str-Funktion verwendet:

>>> version = 3
>>> "Python " + str(version)
'Python 3'

int

Hat man hat eine Benutzereingabe und muss diese in eine Zahl umwandeln, dann braucht man die Funktion int!

Die Funktion int kann nummerische Zeichenketten in ganze Zahlen umwandeln:

>>> program_name = "Python 3"
>>> version_number = program_name.split()[-1]
>>> int(version_number)
3

Man kann int auch verwenden, um eine Fließkommazahl auf eine ganze Zahl abzuschneiden:

>>> from math import sqrt
>>> sqrt(28)
5.291502622129181
>>> int(sqrt(28))
5

Es ist zu beachten, dass beim Dividieren der //-Operator wahrscheinlich besser geeignet ist: int(3 / 2) == 3 // 2.

float

Ist die Zeichenkette, die man in eine Zahl konvertiert, keine ganze Zahl, dann sollte man für diese Konvertierung float anstelle von int verwenden.

>>> program_name = "Python 3"
>>> version_number = program_name.split()[-1]
>>> float(version_number)
3.0
>>> pi_digits = '3.141592653589793238462643383279502884197169399375'
>>> len(pi_digits)
50
>>> float(pi_digits)
3.141592653589793

Man kann float auch verwenden, um ganze Zahlen in Fließkommazahlen zu konvertieren. Dies findet in Python 3 aber im Grunde keine Verwendung mehr.

In Python 2 hat man float verwendet, um ganze Zahlen in Fließkommazahlen zu konvertieren, um eine Float-Division anstelle einer Integer-Division zu erzwingen. In Python 3 gibt es keine „Ganzzahldivision“ mehr (es sei denn, man verwendet speziell den //-Operator), also braucht man float für diesen Zweck nicht mehr. Wenn man also jemals float(x) / y im Python 3-Code sieht, kann man das einfach in x / y ändern.

list

Vorbemerkung: Wenn man in Python eine for-Schleife schreiben kann, um etwas zu durchlaufen, dann ist dieses Etwas ein Iterable.

Möchte man eine Liste aus einem anderen Iterable erstellen, dann ist das mit der Funktion list das möglich:

>>> numbers = [2, 1, 3, 5, 8]
>>> squares = (n**2 for n in numbers)
>>> squares
<generator object <genexpr> at 0x7fd52dbd5930>
>>> list_of_squares = list(squares)
>>> list_of_squares
[4, 1, 9, 25, 64]

Wenn man weiß, dass man mit einer Liste arbeitet, kann man die Methode copy verwenden, um eine neue Kopie einer Liste zu erstellen:

>>> copy_of_squares = list_of_squares.copy()

Wenn man aber nicht weiß, was das Iterable ist, mit dem man arbeitet, ist die list-Funktion der gewöhnliche Weg, um eine Schleife über ein Iterable zu durchlaufen, und es zu kopieren:

>>> copy_of_squares = list(list_of_squares)

Wenn man eine leere Liste erstellen möchte, empfiehlt sich die Verwendung der list-literal-Syntax (die [] Klammern):

>>> my_list = list()  # nicht empfohlen
>>> my_list = [] # empfohlen

Die Verwendung von [] wird als idiomatischer angesehen, da diese eckigen Klammern ([]) tatsächlich wie eine Python-Liste aussehen.

tuple

Die Funktion tuple ist so ziemlich genau wie die list-Funktion, nur dass sie stattdessen Tuple erzeugt:

>>> numbers = [2, 1, 3, 4, 7]
>>> tuple(numbers)
(2, 1, 3, 4, 7)

dict

Die Funktion dict erstellt ein neues Dictionary.

Ähnlich wie list und tuple ist die Funktion dict gleichbedeutend mit dem Durchlaufen einer Schleife über ein Iterable von Schlüssel-Wert-Paaren (key-value-pairs) und dem Erstellen eines Dictionary aus diesen Paaren.

Gegeben ist eine Liste von Zwei-Element-Tupeln:

>>> color_counts = [('red', 2), ('green', 1), ('blue', 3), ('purple', 5)]

Aber anstatt

>>> colors = {}
>>> for color, n in color_counts:
... colors[color] = n
...
>>> colors
{'red': 2, 'green': 1, 'blue' 3, 'purple': 5}

sollte die dict Function verwendet werden:

>>> colors = dict(color_counts)
>>> colors
{'red': 2, 'green': 1, 'blue' 3, 'purple': 5}

Die Funktion dict akzeptiert zwei Arten von Argumenten:

  • ein anderes Dictionary (Mapping ist der Oberbegriff), in diesem Fall wird das Dictionary kopiert
  • eine Liste von Schlüssel-Wert-Tupeln (genauer gesagt, eine Iterable von Zwei-Element-Iterables), aus denen ein neues Dictionary erstellt wird

Dies funktioniert also auch:

>>> colors
{'red': 2, 'green': 1, 'blue' 3, 'purple': 5}
>>> new_dictionary = dict(colors)
>>> new_dictionary
{'red': 2, 'green': 1, 'blue' 3, 'purple': 5}

Die Funktion dict kann auch Schlüsselwortargumente akzeptieren, um ein Dictionary mit String-basierten Schlüsseln zu erstellen:

>>> person = dict(name='Trey Hunner', profession='Python Trainer')
>>> person
{'name': 'Trey Hunner', 'profession': 'Python Trainer'}

In diesen Fällen ist es aber empfehlenswerter, ein dictionary literal zu verwenden:

>>> person = {'name': 'Trey Hunner', 'profession': 'Python Trainer'}
>>> person
{'name': 'Trey Hunner', 'profession': 'Python Trainer'}

Die Literal-Syntax des Dictionary ist flexibler und etwas schneller, aber vor allem vermittelt sie deutlicher, dass man ein Dictionary erstellt.

Wie bei list und tuple sollte auch ein leeres Dictionary mit der literal-Syntax erstellt werden:

>>> my_list = dict()  # nicht empfohlen
>>> my_list = {} # empfohlen

Die Verwendung von {} ist etwas CPU-effizienter, aber vor allem ist es idiomatischer: Es ist üblich, geschweifte Klammern ({}) für die Erstellung eines Dictionary zu verwenden, dict ist viel seltener zu sehen.

set

Die Funktion set erzeugt eine neue Menge. Sie nimmt ein Iterable mit hashbaren Werten (Strings, Zahlen oder andere unveränderliche Typen) und gibt ein set zurück:

>>> numbers = [1, 1, 2, 3, 5, 8]
>>> set(numbers)
{1, 2, 3, 5, 8}

Es gibt keine Möglichkeit, eine leere Menge mit der {}-set-literal-Syntax zu erzeugen (ein einfaches {} ergibt ein Dictionary!), daher ist die set-Funktion die einzige Möglichkeit, eine leere Menge zu erzeugen:

>>> numbers = set()
>>> numbers
set()

Das ist nicht die ganze Wahrheit, denn es ist folgendes möglich:

>>> {*()}  # Dies erstellt ein leeres set!
set()

Aber diese Syntax ist verwirrend (sie beruht auf einer wenig genutzten Funktion des *-Operators), daher ist diese Verwendung nicht zu empfehlen.

range

Die range-Funktion gibt ein Objekt zurück, das einen Zahlenbereich darstellt:

>>> range(10_000)
range(0, 10000)
>>> range(-1_000_000_000, 1_000_000_000)
range(-1000000000, 1000000000)

Der resultierende Zahlenbereich schließt die Startzahl ein, aber nicht die Endzahl (Bereich(0, 10) enthält nicht 10!).

Die range-Funktion ist nützlich, wenn man in einer Schleife einen Zahlenbereich durchlaufen möchte.

>>> for n in range(0, 50, 10):
... print(n)
...
0
10
20
30
40

Ein häufiger Anwendungsfall ist die n-malige Ausführung einer Operation (das ist übrigens eine list comprehension):

first_five = [get_things() for _ in range(5)]