Alle Elemente einer verschachtelten Liste in eine Liste

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
matheblauwal
User
Beiträge: 9
Registriert: Montag 4. März 2013, 19:54
Wohnort: 53639 Königswinter

Was ich eigentlich will ist so etwas wie die Funktion "func":

Code: Alles auswählen

L = [1, 2, [3, 4, [5, 6, 7], 8]]
Li = func(L)
Li soll dann

Code: Alles auswählen

[1, 2, 3, 4, 5, 6, 7, 8]
sein.

Kennt jemand so eine Funktion oder hat eine Idee wie sie aussehen könnte?
Bei n-dimensionalen Listen kann man es über n verschachtelte for-Schleifen lösen, aber hier geht das nicht und auch nicht wenn man gar nicht weiß wie verschachtelt L ist.

Danke für alle Antworten.

PS: Falls es keine eingebaute Funktion gibt, bitte möglichst kurzer Code.
Real Programmers don't comment their code. It was hard to write, it should be hard to understand.
BlackJack

Code: Alles auswählen

def flatten(iterable):
    try:
        for item in iterable:
            for subitem in flatten(item):
                yield subitem
    except TypeError:
        yield iterable


def main():
    L = [1, 2, [3, 4, [5, 6, 7], 8]]
    print list(flatten(L))


if __name__ == '__main__':
    main()
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

Hier eine nicht-rekursive Version, die ich auf der Seite http://rightfootin.blogspot.de/2006/09/ ... atten.html gefunden habe:

Code: Alles auswählen

def flatten(l, ltypes=(list, tuple)):
    ltype = type(l)
    l = list(l)
    i = 0
    while i < len(l):
        while isinstance(l[i], ltypes):
            if not l[i]:
                l.pop(i)
                i -= 1
                break
            else:
                l[i:i + 1] = l[i]
        i += 1
    return ltype(l)
Vorteile gegenüber der rekursiven Version: Die Listen können beliebig tief verschachtelt sein, es wird niemals das Rekursionslimit erreicht. Ein Nachteil ist evtl. das dieser Code explizit auf Typen überprüft (hier per Default auf list und tuple), während der Code von BlackJack mit allen iterables funktioniert (und damit auch mit basestring-Objekten).
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

derdon hat geschrieben:Ein Nachteil ist evtl. das dieser Code explizit auf Typen überprüft (hier per Default auf list und tuple), während der Code von BlackJack mit allen iterables funktioniert (und damit auch mit basestring-Objekten).
Außer man überprüft nicht auf einzelne iterierbare types sondern benutzt stattdessen `collections.Iterable`:

Code: Alles auswählen

def nested2flat(*elements):
    for item in elements:
        if isinstance(item, collections.Iterable) and len(item) > 1:
            for inner_item in nested2flat(*item):
                yield inner_item
        else:
            yield item
Allerdings ist BlackJacks Lösung definitiv die "schönere"...

mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
BlackJack

@mutetella: Nicht alles was iterierbar ist kann man mit diesem `isinstance()` testen und man kann ebenfalls nicht die Länge von allen iterierbaren Objekten ermitteln.
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

Ok... lasst es uns in den Müll kicken... :mrgreen:
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
bords0
User
Beiträge: 234
Registriert: Mittwoch 4. Juli 2007, 20:40

derdon hat geschrieben:Vorteile gegenüber der rekursiven Version: Die Listen können beliebig tief verschachtelt sein, es wird niemals das Rekursionslimit erreicht. Ein Nachteil ist evtl. das dieser Code explizit auf Typen überprüft (hier per Default auf list und tuple), während der Code von BlackJack mit allen iterables funktioniert (und damit auch mit basestring-Objekten).
Außer, dass der Code von BlackJack eben nicht mit strings funktioniert.
BlackJack

Den notwendigen Test auf `basestring` kann man aber sehr einfach einbauen.
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

bords0 hat geschrieben:
derdon hat geschrieben:Vorteile gegenüber der rekursiven Version: Die Listen können beliebig tief verschachtelt sein, es wird niemals das Rekursionslimit erreicht. Ein Nachteil ist evtl. das dieser Code explizit auf Typen überprüft (hier per Default auf list und tuple), während der Code von BlackJack mit allen iterables funktioniert (und damit auch mit basestring-Objekten).
Außer, dass der Code von BlackJack eben nicht mit strings funktioniert.
Doch, er funktioniert mit Strings. Nur eben nicht so, wie du es erwartest ;) Wie Unterklassen von list und wie tuple behandelt werden sollen, ist doch auch reine Definitionssache.
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

@derdon: nein! Die Elemente eines Strings sind wieder Strings (halt mit nur einem Zeichen), die wiederum iterierbar sind, was eine „endlose“ Rekursion zur Folge hat.
BlackJack

@derdon: Es dürfte mit Zeichenketten *nicht* funktionieren. Zeichenketten sind iterierbar. Die Elemente sind einzelne Zeichen — in Form einer Zeichenkette. Also iterierbar. Die Elemente sind einzelne Zeichen — in Form einer Zeichenkette. Also iterierbar. Die Elemente sind einzelne Zeichen — in Form einer Zeichenkette. Also iterierbar. Die Elemente sind einzelne Zeichen — in Form einer Zeichenkette. Also iterierbar… ;-)

Edit: Verdammt. Zu lange mit dem absenden gewartet. :-)
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

@Blackjack: aber der versuch eine endlose Iteration in einem Fließtext unterzubringen gibt 10 Bonusminuten. :)
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

Das kommt davon, wenn man über Code redet, den man selber nicht getestet hat :oops:
matheblauwal
User
Beiträge: 9
Registriert: Montag 4. März 2013, 19:54
Wohnort: 53639 Königswinter

Hey, danke für alle eure Antworten! :D
Ich denke ich werde den Code von derdon benutzen, weil es bei einer solch verschachtelten Liste auch Listenelemente geben kann die Strings sind.
Real Programmers don't comment their code. It was hard to write, it should be hard to understand.
Antworten