tief verschachtelte Liste "entschachteln"
Verfasst: Freitag 16. April 2010, 20:41
Hey, ich habe aus Interesse mal einen rekursiven Algorithmus entwickelt, um eine tief verschachtelte Liste zu "entschachteln".
Als Test-Liste habe ich das hier genommen:
Das schien mir schon relativ effizient zu sein, aber dann hab ich mir gedacht, dass Listen ja ziemlich ineffizient sind und habe versucht, das über Generatoren zu lösen:
Das war erwartungsgemäß schneller:
Bei 1.000.000 Durchläufen braucht tiefe() ca. 50 Sekunden und tiefe2() ca. 0.35 Sekunden
Ein "kleiner" Unterschied von ca. 1:143
Aber beim Aufsummieren mittels sum() gewinnt die Liste wieder deutlich (mehrere Sekunden).
Mit einer dritten Implementation speziell zum Addieren aller Werte der Liste kann ich noch mal einige Sekunden rausschlagen:
Naja meine Fragen:
Wie könnte man das am effizientesten lösen? Gibt es bessere Algorithmen oder besser geeignete Datenstrukturen?
Mit dem Generator kann ich die Liste zwar sehr schnell entschachteln, aber im Endeffekt verliere ich Zeit, da die Datenstruktur wohl nicht so schnell arbeitet wie list.
Die Rekursion sollte ja eigentlich nicht so viel ausmachen oder? Bei dieser Liste zum Beispiel sind es nur 16 Selbstaufrufe und nicht gleich 10000 oder so
Aber vielleicht geht es irgendwie effizienter, wenn man Ebene für ebene durchgeht, anstatt immer "hoch und runter". Aber darüber muss ich erst noch mal nachdenken ...
PS: Was ist denn der übliche Weg dafür? Gibt es schon etwas fertiges in Python?
Danke schon mal für eure Antworten
Code: Alles auswählen
def tiefe(iterable):
res = []
for element in iterable:
if hasattr(element, "__iter__"):
res += tiefe(element)
else:
res.append(element)
return res
Code: Alles auswählen
a = [5, 2, 3, [4, 6, 1, [4, 5, [3, 2, [3, [5, 3, 2, 3], [4, 32], 4, [2, 3, [1, 2], 5, [5, 7, [3, 8, 2, [9, 1, 2, 6, 99, 4]]]]]
, 6], 3, [54, 2, 3]]], [99, 1, [3, 4]], [2], 98]
Code: Alles auswählen
def tiefe2(iterable):
for element in iterable:
if hasattr(element, "__iter__"):
for i in tiefe2(element):
yield i
else:
yield element
Bei 1.000.000 Durchläufen braucht tiefe() ca. 50 Sekunden und tiefe2() ca. 0.35 Sekunden
Ein "kleiner" Unterschied von ca. 1:143

Aber beim Aufsummieren mittels sum() gewinnt die Liste wieder deutlich (mehrere Sekunden).
Mit einer dritten Implementation speziell zum Addieren aller Werte der Liste kann ich noch mal einige Sekunden rausschlagen:
Code: Alles auswählen
def deep_sum(iterable):
res = 0
for element in iterable:
if hasattr(element, "__iter__"):
res += deep_sum(element)
else:
res += element
return res
Naja meine Fragen:
Wie könnte man das am effizientesten lösen? Gibt es bessere Algorithmen oder besser geeignete Datenstrukturen?
Mit dem Generator kann ich die Liste zwar sehr schnell entschachteln, aber im Endeffekt verliere ich Zeit, da die Datenstruktur wohl nicht so schnell arbeitet wie list.
Die Rekursion sollte ja eigentlich nicht so viel ausmachen oder? Bei dieser Liste zum Beispiel sind es nur 16 Selbstaufrufe und nicht gleich 10000 oder so

Aber vielleicht geht es irgendwie effizienter, wenn man Ebene für ebene durchgeht, anstatt immer "hoch und runter". Aber darüber muss ich erst noch mal nachdenken ...
PS: Was ist denn der übliche Weg dafür? Gibt es schon etwas fertiges in Python?
Danke schon mal für eure Antworten
