Benutzer-Werkzeuge

Webseiten-Werkzeuge


python

Python

Python ist eine interpretierte höhere Programmiersprache, die häufig als Skriptsprache eingesetzt wird. Die Version Python 2 wird seit April 2020 nicht mehr unterstützt.

Übersicht über nützliche Bibliotheken

Name Einsatzzweck
configobj Parsen von Konfigurationsdateien
argparse Parsen von Kommandozeilenoptionen, auch zum Parsen von Konfigurationsdateien, configobj ist dabei jedoch komfortabler
matplotlib Erzeugen von Plots
pandas Datenanalyse

Standard-Library

Switch-Case

Python kennt keine Switch-Case-Anweisung. Die Funktion kann mit If-Else-Anweisung nachgebildet werden, es gibt aber auch weitere Möglichkeiten.

For-Schleifen

In der normalen For-Schleife mit range müssen die Argumente Integers sein:

for i in range(start, stop, step):

Sind sie Floats kann arange aus numpy verwendet werden:

for i in numpy.arange(start, stop, step):

Für eine feste Anzahl von Schritten, kann linspace verwendet werden:

for i in numpy.linspace(start, stop, nrSteps):

Wird der Index einer For-Schleife benötigt, kann enumerate verwendet werden:

ints = [8, 23, 45, 12, 78]
for idx, val in enumerate(ints):
    print idx, val

String-Formatting

Python unterstützt zwei verschiedene Möglichkeiten zur Stringinterpolation: den %-Operator und .format(). Letzteres ist die neuere und empfohlene Variante.

Beispiel:

#alt
'%s %s' % ('eins', 'zwei') 
#neu
'{} {}'.format('eins', 'zwei')

Bools ausgeben

Um boolsche Werte in anderen textueller Darstellung als True/False auszugeben kann man diesen Trick verwenden:

print "state: {0}".format(['Off','On'][state])

Modul neu laden

Um ein bereits importiertes Modul neu zu laden (z.B. um globale Variablen zurück zu setzen), muss ein reload durchgeführt werden. Je nach Python-Version liegt diese Funktion in einem anderen Modul:

Python-Version Befehl
2
reload(module)
3-3.3
import imp
imp.reload(module)
>3.4
import importlib
importlib.reload(module)

Buffering

Standardmäßig ist die Ausgabe von Python gebuffert. Das kann insbesondere bei der Verwendung von Umleitungen command > out.txt oder dem Einsatz von tee (command | tee out.txt) und langen Skriptlaufzeiten störend sein. Folgende Möglichkeiten existieren zur Lösung:

  • Mit sys.stdout.flush() explizit einen Flush des Buffers anfordern
  • Das Skript mit python -u aufrufen (geht auch in Shebang-Zeile). Damit sind alle Ausgaben ungebuffert.
  • Seit Python 3.3 kennt print den Parameter flush:
     print('Test', flush=True) 
  • Vor dem ersten print-Befehl folgendes aufrufen:
    sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0) 

    Damit sind alle Ausgaben ungebuffert.

Quelle

mehrfache Einträge aus Liste entfernen

Mehrfache Einträge aus Listen lassen sich durch die Umwandlung in ein Set (und eine Rückumwandlung in eine Liste) entfernen:

unique_list = list(set(nonunique_list))

Die Einträge sind dann ungeordnet.

String zu Liste konvertieren

Soll ein String zu einer Liste mit einem Element umgewandelt werden, können eckige Klammern [] verwendet werden:

test_string = "abc"
text_list = [test_string]
#text_list = ["abc"]

Der Befehl list erzeugt dagegen eine Liste bestehend aus den einzelnen Zeichen des Strings:

test_string = "abc"
text_list = list(test_string)
#text_list = ['a', 'b', 'c']

NaN erzeugen

Ein NaN (Not a Number) kann mit float('NaN') erzeugt werden. Seit Python 3.5 kann auch math.nan verwendet werden.

Exceptions

argparse

Matplotlib

lmodern mit T1-Encoding

Um mit matplotlib PDF-Dateien mit der Schriftart lmodern und korrektem T1-Encoding zu erstellen (zum Beispiel für richtig kopierbare Umlaute) muss LaTeX anstelle des internen Mechanismus von matplotlib verwendet werden. Dazu sind folgende Einstellung notwendig:

plt.rcParams['text.latex.preamble']=[r"\usepackage{lmodern} \usepackage[T1]{fontenc}"]
params = {
          'text.usetex' : True,
          'text.latex.unicode': True,
          'font.family' : "lmodern"
         }
plt.rcParams.update(params)

Das Setzen von \usepackage{lmodern} vor den anderen Optionen ist notwendig, siehe http://stackoverflow.com/a/18633695


Der Textsatz mit LaTeX ist deutlich langsamer als der interne Mechanismus von matplotlib.

LaTeX wird nicht im aktuellen Arbeitsverzeichnis ausgeführt, sondern im Cache-Verzeichnis (~/.cache/matplotlib unter Linux oder über get_cachedir() herausfinden). Deshalb funktioniert \input mit relativen Pfaden nicht. Die TeX-Dateien verbleiben im Cache-Verzeichnis und können zum Debugging nützlich sein.

"Unknown Font" in Python 3

Wird eine Grafik mit matplotlib unter Python 3 als PDF exportiert, werden die Fonts im PDF mit pdffonts oder PDF-Viewern wie Okular u.U. als „unknown font“ angezeigt. Dabei handelt es sich um diesen Bug.

Abhilfe:

  • Python 2 verwenden oder
  • eine aktuelle matplotlib-Version verwenden

Achsenbeschriftung in wissenschaftlicher Schreibweise

Mit der Funktion ticklabel_format kann die Achsenbeschriftung in wissenschaftlicher Schreibweise gesetzt werden.

mpl.ticklabel_format(style='sci', scilimits=(-3,4), axis='both')

Die Defaultwerte für scilimits werden in rcParams durch axes.formatter.limits gesetzt.

Nur Ganzzahlen als Achsenbeschriftung

Der einfachste Weg nur Ganzzahlen als „Ticks“ auf den Achsen anzuzeigen, ist dieser:

from matplotlib.ticker import MaxNLocator
 
ax = plt.figure().gca()
ax.yaxis.set_major_locator(MaxNLocator(integer=True))

Ränder beim Autoscaling

Um zu verhindern, dass die Datenpunkte nicht mehr auf den Achsen liegen und daher schlecht zu erkennen sind, gibt es zwei Möglichkeiten. Entweder kann in der matplotlibrc folgendes gesetzt werden:

axes.xmargin        : 0.1  
axes.ymargin        : 0.1  

Dies wirkt dann für alle Plots. Um jeden Plot individuell zu ändern:

plt.plot(t,np.sin(t))
plt.margins(x=0.1, y=0.1)

Der angegebene Werte kann jeweils zwischen 0 und 1 liegen.

Innerhalb von Subplots müssen die Ränder für jede Achse separat gesetzt werden, plt.margins() wirkt nur auf die letzte:

for ax in axes:
   ax.margins(x=0.1, y=0.1)

Configobj

configobj ist eine Klasse mit der Konfigurationsdateien einfach geparst und die geparsten Werte valididert werden können.

Validierung der Argumente

Mit dem validator-Objekt können die Argumente gegen eine Spezifikation („configspec“) geprüft und in den entsprechenden Typ umgewandelt werden, hier eine Liste der möglichen Argumenttypen.

Die in der configspec angegebenen Typen werden nicht geprüft. Tippfehler (z.B. bool vs. boolean) werden daher nicht erkannt und der Typ des Arguments bleibt unverändert.

Validierung von Listen mit nur einem Argument

Gibt man in der configspec zur Validierung string_list an und enthält die zugewiesene Liste nur ein Element, wird der String in eine Liste von Buchstaben zerlegt. Benötigt man eine Liste mit einem Element muss die Zuweisung mit einem Komma am Ende erfolgen:

testvar = "teststring",

Alternative kann die configspec auf force_list geändert werden. Dabei wird allerdings keine Typprüfung vorgenommen.

Schriftgröße der Legende

Die einfachste Art die Schriftgröße der Legende zu verändern ist diese:

plot.legend(prop={'size':6})

Tick-Frequenz ändern

Um den Abstand der Ticks manuell zu setzen, kann der MultipleLocator verwendet werden. Als Argument bekommt er den Abstand der Ticks.

import matplotlib.ticker as ticker
 
ax.xaxis.set_major_locator(ticker.MultipleLocator(tick_spacing))

Links

csv

Zeilenende

Standardmäßig wird beim Schreiben das Windowszeilenende \r\n benutzt. Um dies zu ändern, kann der lineterminator explizit gesetzt werden:

writer = csv.writer(f, lineterminator='\n')

setuptools

Vergleichen von Versionsnummern

Mit der Funktion parse_version lassen sich komfortabel auch komplizierte Versionsnummern vergleichen:

from pkg_resources import parse_version
if parse_version('2.1-rc2') < parse_version('2.1'):
    print "Version is to low!"

Die Version von Python-Modulen lässt sich über die __version__-Eigenschaft herausfinden:

import scipy
print scipy.__version__

numpy

alle Inf in Array durch Null ersetzen

Alle INFs in einem Numpy-Array lassen sich wie folgt durch Null oder einen beliebigen anderen Wert ersetzen:

from numpy import inf
x =  numpy.array([-inf, -inf, 37.49668579])
x[x == inf] = 0

UTF-8

Python 3 unterstützt UTF-8 gut und komfortabel. In Python 2 muss das Encoding eines Sourcefiles mit

# -*- coding: utf-8 -*-

oder

# coding: utf8

explizit gesetzt werden und Strings müssen das Präfix u bekommen:

some_string = u'ÜÖÄ'

Tipps & Tricks

Prüfen, ob String numerisch

Um zu prüfen, ob ein String numerisch ist, ist es häufig nicht sinnvoll, die Funktionen isdigit() oder isnumeric() (nur für Unicodestrings definiert) zu verwenden, da diese keine negativen Zahlen akzeptieren. Als Alternative kann man sowas verwenden:

def isnumeric(value)
try:
   val = float(value)
   return True
except ValueError:
   return False

Links

python.txt · Zuletzt geändert: 2024/04/01 07:55 von olli