ich bin auf verschiedene Threads auf stackoverflow gestoßen, wie man Listen "flattened".
Naja, um ehrlich zu sein habe ich einige gute Sachen gefunden, wie z.Bsp [item for sublist in list for item in sublist]...
Aber eigentlich wollte ich was ganz was anderes: selber bestimmen, bis zu welcher "Tiefe" geflattet wird.
Sorry for mein Denglisch.
Also hab ich mich rangesetzt und bisher eine Möglichkeit gefunden, wie ich Listen mit beliebiger Tiefe rekursiv "flatt'ne":
Code: Alles auswählen
def flatten(l):
try:
for i in l:
try:
for j in flatten(i):
yield j
except TypeError:
yield i
except TypeError:
yield l
(Hatte zwischendurch auch Versionen, die denselben Job ohne Einhaltung der Reihenfolge machen...)
Zur Veranschaulichung:
Code: Alles auswählen
>>> l
[[0, 1], [3, 4, [5, 6]], [7, 8, [9, 10, [11, 12, [13, 14]]]]]
>>> list(flatten(l))
[0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
Jetzt bin ich aber ein bischen über mein Ziel hinausgeschoßen.
Eigentlich will ich flatten(l, limit=N) haben, wobei limit=0 unendlich rekursiv geht, wie flatten(l).
Und limit > 0, z.Bsp. limit=1 geht nur auf eine Ebene runter:
limit=1
Code: Alles auswählen
>>> l
[[0, 1], [3, 4, [5, 6]], [7, 8, [9, 10, [11, 12, [13, 14]]]]]
>>> list(flatten(l, limit=1))
[0, 1, 3, 4, [5, 6], 7, 8, [9, 10, [11, 12, [13, 14]]]]
Code: Alles auswählen
>>> l
[[0, 1], [3, 4, [5, 6]], [7, 8, [9, 10, [11, 12, [13, 14]]]]]
>>> list(flatten(l, limit=2))
[0, 1, 3, 4, 5, 6, 7, 8, 9, 10, [11, 12, [13, 14]]]
Code: Alles auswählen
>>> l
[[0, 1], [3, 4, [5, 6]], [7, 8, [9, 10, [11, 12, [13, 14]]]]]
>>> list(flatten(l, limit=3))
[0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, [13, 14]]
Code: Alles auswählen
>>> l
[[0, 1], [3, 4, [5, 6]], [7, 8, [9, 10, [11, 12, [13, 14]]]]]
>>> list(flatten(l, limit=4))
[0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
Interessiert sich jemand für dieses Problem? Wenn ja, bitte ich um Hilfe.
Ich fände so eine flatten(list, limit=N) Funktion sowas von nützlich... sollte eigentlich ein PEP für ein builtin werden, findet ihr nicht?
Vielen Dank wie immer im Voraus.
[SOLVED]
EDIT: Das ging schneller als gedacht, hier die Lösung mit Dank an EyDu:
Code: Alles auswählen
def flatten(l, limit=0):
assert limit >= 0 or limit is None
if limit == 0 or limit is None:
for e in l:
yield e
else:
for e in l:
if not isinstance(e, list):
yield e
else:
if not isinstance(e, basestring):
for x in flatten(e, None if limit is None else limit-1):
yield x
else:
yield e
Code: Alles auswählen
>>> l = [[0, 1], [3, 4, [5, 6]], [7, 8, [9, 10, [11, 12, [13, 14]]]]]
>>> list(flatten(l))
[0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
>>> list(flatten(l, limit=1))
[0, 1, 3, 4, [5, 6], 7, 8, [9, 10, [11, 12, [13, 14]]]]
>>> list(flatten(l, limit=2))
[0, 1, 3, 4, 5, 6, 7, 8, 9, 10, [11, 12, [13, 14]]]
>>> list(flatten(l, limit=3))
[0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, [13, 14]]
>>> list(flatten(l, limit=4))
[0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
>>> list(flatten(l, limit=5))
[0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
>>> l = [[0, 1], [3, 'Hallo Welt!', [5, 6]], [7, 8, [9, 10, [11, 12, [13, 14]]]]]
>>> list(flatten(l, limit=5))
[0, 1, 3, 'Hallo Welt!', 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]