Essentielles, auf Institutsrechnern bereits verfügbar:
Empfehlenswert:
Direkt lauffähige, recht vollständige Distribution mit aktuellen Programmversionen (Linux ohne Root, Windows, OSX):
Dokumentation zum Einstieg:
helloworld.py:
#!/usr/bin/env python
print "Hello World"
Ausführung:
max@max-ThinkPad-X220:~/lehre/2013-python-tutorial$ python helloworld.py
Hello World
Interaktiver Interpreter (python
oder ipython
):
max@max-ThinkPad-X220:~/lehre/2013-python-tutorial$ python
Python 2.7.3 (default, Aug 1 2012, 05:14:39)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> print "Hello World"
Hello World
>>>
In diesem Notebook eingebetteter Interpreter:
print "Hello World"
x = 1 # int
y = 0.73 # float
z = 'Hallo' # string
a = x + y # float
print a
x = z # x jetzt string
a = x + y # Fehler
Verschiedene Integer-Typen
print 25**2 # int
print 25**200 # arbitrary precision
Floating point
2.6+7.8
2.5**2
2.5**(1./10)
Warnung: Integer- vs. Float-Division -- Fehlerquelle
f = 2/3
f
f = (2/3) * 1.5
f
f = float(2) / 3
f
Ab Python 3.0 liefert /
immer Fließkommawerte, für Integerdivision
gibt es den neuen Operator //
. Wir behelfen uns bei Python 2.x auf
folgende Art:
from __future__ import division
2/3
2//3
Mathematische Funktionen und Konstanten liegen im Modul math
import math
math.sin(math.pi / 2)
Nützlich im interaktiven Interpreter:
dir(math) # Variablen, Funktionen etc. definiert
# im Modul
help(math.sin) # Dokumentation anzeigen
Komplexe Zahlen
import cmath
cmath.sqrt(-1)
cmath.exp(1j * cmath.pi / 3)
a = 'Hello ' # Single quotes
b = "World " # Double quotes
c = "Bob said 'hey there.'" # A mix of both
d = "\'"
print d
e = b + a # concatenate
print e
f = a*3
print f
Elementzugriff (Indizierung beginnt bei 0), Slicing [erstes Element:Position hinter letztem Element]
c[5] # (5+1). Element von c
c[2:8] # (3.-8.). Element von c
c[:3]
c[-12:] # negative Zahlen zählen vom Ende zurück
c[:]
String-Methoden: Funktionen, die auf einem Zeichenkettenobjekt operieren.
c.count('e')
c.upper()
"abracadabra".find("ra")
"abracadabra".replace("ra", "lu")
c[3] = 'a'
Strings sind unveränderliche Objekte, ggf. werden neue Strings von den Methoden zurück geliefert.
e="abracadabra"
print e.replace("ra", "lu")
print e
Zusammenfassung beliebiger Objekte
L = [ 1, 5, 9, 45, 3, 72, 27 ]
len(L)
Elementzugriff wie bei Zeichenketten
L[6]
L[8]
Listen können verändert werden
L[2] = 11
L
L.sort()
L
L.append(87)
L
L.insert(2, 33) # an Position 2 einfügen
L
del L[3:5] # Loesche Element 4-5
L
K=[0]*10 # List mit 10 Elementen, alle 0
K
M = [1, 2.45, (1+4j), L[1:5]] # mixed list
M
M[3][2]
Mit range()
Listen aus Zahlenbereichen erzeugen
G = range(20)
G
G = range(1, 11)
G
G = range(1, 11, 2)
G
import numpy as np
np.arange(1, 10, 0.2)
Slicing
a = range(10)
a
a[4:7]
a[-3:]
a[-3:-1]
a[-3:2]
"assoziatives Array", "map": Verknüpfung von (Schlüssel, Wert)-Paaren
D = {'food':'Spam', 'quantity':4, 'color':'pink'}
D['food']
D['size'] # nichtgesetzter Schlüssel
Dictionaries sind veränderlich wie Listen
D['quantity'] = 6
D['size'] = 20 #neuer Schlüssel
D
Boolsche Werte
1 < 4
5 < 4
0.3 == 0.1 + 0.2
Logische Ebenen im Code werden nur durch :
und Einrückung ausgedrückt -- keine Klammern oder begin
-end
-Blöcke
Bedingungen mit if
a = 1
b = 2
c = 3
if a < b:
if c > b:
print 1
print a, b, c
else:
print 2
else:
print 3
x = 'spam'
while x: # wiederhole, solange Bedingung "wahr", d.h. x != ''
print x,
x = x[:-1] # letztes Zeichen entfernen
for-Schleife: iteriere über alle Elemente einer Liste:
for x in ['spam', 'eggs', 'ham']:
print x,
Für "klassiche" for-Schleifen: Kombination mit range()
for i in range(0, 10, 2):
print i,
Aufgabe: Finde alle Quadrate der natürlichen Zahlen bis 10
C-artiger Code:
l = []
for i in range(1, 11):
l.append(i**2)
print l
"Pythonischer" Code:
l = [ i**2 for i in xrange(1,11) ]
print l
Auch kompliziertere Ausdrücke möglich:
l1 = []
for i in range(1,7):
for word in ['sausages', 'spam', 'eggs', 'ham']:
if i <= len(word):
l1.append(word*i)
print l1
print
l2 = [word*i for i in range(1,7) for word in ['sausages', 'spam', 'eggs', 'ham'] if i <= len(word)]
print l1 == l2
def square(argument):
return argument*argument
square(3)
Funktionen sind Objekte, wie Variablen zu verwenden
def applyToList(f, l):
return [f(x) for x in l]
applyToList(square, range(11))
Achtung: Funktionsargumente werden als Referenz übergeben, nicht als kopierter Wert
def dreiGroesste(l):
l.sort()
return l[-3:]
l = [17, 2, 81, 30, -45]
print l
print dreiGroesste(l)
print l # Liste hat sich verändert
Abhilfe: Explizit kopieren
def dreiGroesste1(liste):
l = liste[:] # kopiere alle Eintraege (Slice-Notation)
l.sort()
return l[-3:]
l = [17, 2, 81, 30, -45]
print dreiGroesste1(l)
print l
print sorted(l[-3:])
def dreiGroesste2(liste):
from copy import copy # eine Funktion aus einem Modul importieren ("shallow copy")
l = copy(liste)
l.sort()
return l[-3:]
l = [17, 2, 81, 30, -45]
print dreiGroesste1(l)
print l
Tupel sind ähnlich zu Listen, können nach dem Erzeugen aber nicht verändert werden
tup = (1, 2, 3) # Klammern optional
tup[2]
tup[2] = 5
Tupel werden gerne verwendet, um mehrere Werte von einer Funktion zurückzugeben
def squareAndCube(x):
return [x**2, x**3]
s, c = squareAndCube(5)
print s
s += 2
print s
print c
import copy
l1 = [ [1, 2, 3], [4, 5, 6] ]
l2 = copy.copy(l1)
print l1
print l2
l2[0] = "zonk"
print l1
print l2
l2 = copy.deepcopy(l1)
l2[0][0] = "zonk"
print l1
print l2
help(copy)
C-schnelle Routinen für große Felder
import numpy as np
a = np.arange(15) # range() für Arrays
a = a.reshape(3,5) # 3 Zeilen, 5 Spalten
a
print a.shape
print a.ndim
print a.size
Arrays aus beliebigem iterierbaren Objekt erzeugen, Datentyp explizit festlegen
a = np.array([x**2 for x in range(10)], dtype='float')
a
a = np.array( [ [x*y for x in range(5)] for y in range(4)] )
a
Rechenoperationen auf Arrays:
x = np.linspace(0, 2*np.pi, 20)
x
y = np.cos(x)
y
2 * np.linspace(0, 2*np.pi, 20) + y
Vektor-/Matrizenrechnung, Zufallszahlen
A = np.random.random(20).reshape(5,4)
A
A.transpose()
B=np.random.random(4)
np.dot(A,B)
Zugriff auf Elemente, Zeilen, Spalten mit Slice-Notation
A[1, 1] # Zeile, Spalte; Zählen ab 0
A[1, :] # Zeile 1
A[:, 2:4] # Spalten 2 und 3
A.trace()
D = np.random.random([5,5])
D
Viele Lineare-Algebra-Routinen in den Modulen numpy.linalg
np.linalg.det(D)
D.shape, A.shape
x = np.linalg.solve(D, A) # Löse D x = A
x
A2 = np.dot(D, x)
np.max(np.abs((A - A2)))
Q,R = np.linalg.qr(D)
Q
np.linalg.det(Q)
R
Am einfachsten in Textdateien mit numpy:
np.savetxt("R.dat", R)
cat R.dat
R2 = np.loadtxt("R.dat")
R2
Python-Bordmittel
with open('test.dat', 'w') as f: # with Block: Datei sicher geschlossen
f.write('Test1\nTest2')
cat test.dat
with open('test.dat', 'r') as f:
for n, l in enumerate(f.readlines()):
print n, l.strip()
import numpy as np
import matplotlib.pyplot as plt
plt.figure(figsize=(10,6))
for d in [4, 20, 500]:
x_values = np.linspace(0, 4, d)
y_values = [ np.sqrt(x) for x in x_values ] # äquivalent: y_values = np.sqrt(x_values)
plt.plot(x_values, y_values, label=str(d))
plt.xlabel("x");
plt.ylabel("y");
plt.legend()
fig = plt.gcf()
plt.show()
fig.savefig("test.pdf")
2D-Plots
def f_plus(x,y):
return np.sqrt(3+2*np.cos(np.sqrt(3)*y)+4*np.cos(x)*np.cos(np.sqrt(3)/2*y))
def f_minus(x,y):
return -np.sqrt(3+2*np.cos(np.sqrt(3)*y)+4*np.cos(x)*np.cos(np.sqrt(3)/2*y))
X = np.arange(-3.14, 3.14, 0.1)
Y = np.arange(-3.14, 3.14, 0.1)
fig = plt.figure()
Z_plus = np.array([[f_plus(x,y) for x in X] for y in Y])
Z_minus = [[f_minus(x,y) for x in X] for y in Y]
plt.imshow(Z_plus)
plt.show()
3D-Darstellung
XX,YY = np.meshgrid(X,Y)
XX,YY
from mpl_toolkits.mplot3d import axes3d
XX,YY = np.meshgrid(X,Y)
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_wireframe(XX, YY, Z_plus, color='black')
ax.plot_wireframe(XX, YY, Z_minus, color='black')
plt.show()
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(XX, YY, Z_plus, cmap='jet', linewidth=0, antialiased=True, vmin=-3, vmax=3, rstride=1, cstride=1)
ax.plot_surface(XX, YY, Z_minus, cmap='jet', linewidth=0, antialiased=True,vmin=-3, vmax=3, rstride=1, cstride=1)
plt.show()