>>> a = ['spam', 'eggs', 100, 1234]
>>> a
['spam', 'eggs', 100, 1234]
>>> a[0]
'spam'
>>> a[3]
1234
>>> a[-2]
100
>>> a[2] = a[2] + 23
>>> a
['spam', 'eggs', 123, 1234]
>>> tel = {'paul':57757, 'barbara':45304}
>>> tel['guido'] = 89003
>>> tel
{'barbara': 45304, 'guido': 89003, 'paul': 57757}
>>> tel['barbara']
45304
>>> tel.keys()
['paul', 'barbara', 'guido']
>>> 'guido' in tel
True
>>> korb = ['Apfel', 'Orange', 'Apfel', 'Birne', 'Orange', 'Banane']
>>> frucht = set(korb)
>>> frucht
set(['Apfel', 'Banane', 'Birne', 'Orange'])
>>> 'Orange' in frucht
True
>>> 'Kiwi' in frucht
False
So macht Mengenlehre Spass...
>>> a = set('abracadabra')
>>> b = set('alacazam')
>>> a # Buchstaben in a
set(['a', 'r', 'b', 'c', 'd'])
>>> a - b # ... die es in a gibt aber nicht in b
set(['r', 'd', 'b'])
>>> a | b # ... von a und b
set(['a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'])
>>> a & b # ... die in beiden vorhanden sind
set(['a', 'c'])
>>> a ^ b # ... in a oder b, aber nicht in beiden
set(['r', 'd', 'b', 'm', 'z', 'l'])
Die Fibonacci-Folge lautet:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
def fib(n):
if n == 0: return 0
if n == 1: return 1
return fib(n - 1) + fib(n - 2)
print fib(10)
$ python fib.py
55
$ chmod +x fib.py
$ ./fib.py
55
#!/usr/bin/env python
# -*- coding: utf-8 -*-
def fib(n):
"""Berechnet die n-te Zahl der Fibonacci-Folge
>>> fib(0)
0
>>> fib(1)
1
>>> fib(10)
55
"""
if n == 0: return 0
if n == 1: return 1
return fib(n - 1) + fib(n - 2)
print fib(10)
$ python -m doctest -v fib.py
Trying:
fib(0)
Expecting:
0
ok
...
3 passed and 0 failed.
Test passed.
Der selbe Code, aber diesmal berechnen wir fib(30).
Um die Zeit zu messen starten wir das Programm mit dem Profiler.
$ python -m cProfile fib.py
832040
2692539 function calls ... in 9.859 seconds
...
Sehr langsam. Fast 10 Sekunden für die 30-igte Fibonacci Zahl!
Fibonacci in C implementiert:
long fib(int);
long fib(int n) {
if (n == 0) return 0;
if (n == 1) return 1;
return fib(n - 1) + fib(n - 2);
}
Als Library kompilieren:
$ gcc -shared -Wl,-soname,libfib -o libfib.so -fPIC libfib.c
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""Berechnet die n-te Zahl der Fibonacci-Folge
>>> lib.fib(0)
0
>>> lib.fib(1)
1
>>> lib.fib(10)
55
"""
import ctypes
lib = ctypes.CDLL('./libfib.so')
print lib.fib(30)
Super Schnell: nur noch 0.065
Aber was ist mit grösseren Fibonacci zahlen?
Tipp: Schon im ersten Programm steckt der Wurm drinn.
Wieso ist der Code so langsam bei grösseren Zahlen? Eine einfache Analyse.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
def fib(n):
"..."
print "fib wurde mit n =", n, "aufgerufen"
if n == 0: return 0
if n == 1: return 1
result = fib(n - 1) + fib(n - 2)
return result
fib(10)
$ python fib.py
fib wurde mit n = 10 aufgerufen
fib wurde mit n = 9 aufgerufen
fib wurde mit n = 8 aufgerufen
fib wurde mit n = 7 aufgerufen
...
fib wurde mit n = 0 aufgerufen
fib wurde mit n = 1 aufgerufen
fib wurde mit n = 4 aufgerufen
fib wurde mit n = 3 aufgerufen
fib wurde mit n = 2 aufgerufen
fib wurde mit n = 1 aufgerufen
fib wurde mit n = 0 aufgerufen
fib wurde mit n = 1 aufgerufen
fib wurde mit n = 2 aufgerufen
fib wurde mit n = 1 aufgerufen
fib wurde mit n = 0 aufgerufen
Da wird fib() immer wieder mit den selben Parametern aufgerufen und neu berechnet.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
cache = {}
def fib(n):
"..."
if (n in cache): return cache[n]
if n == 0: return 0
if n == 1: return 1
result = fib(n - 1) + fib(n - 2)
cache[n] = result
return result
print fib(30)
Das Zahl wird jetzt in weniger als 0.001 Sekunden berechnet :D