568 Stimmen

Eine unregelmäßige Liste von Listen abflachen

Ja, ich weiß, dass dieses Thema schon einmal behandelt wurde ( aquí , aquí , aquí , aquí ), aber soweit ich weiß, scheitern alle Lösungen, außer einer, an einer solchen Liste:

L = [[[1, 2, 3], [4, 5]], 6]

Die gewünschte Leistung ist

[1, 2, 3, 4, 5, 6]

Oder vielleicht noch besser, ein Iterator. Die einzige Lösung, die ich gesehen habe, die für eine beliebige Verschachtelung funktioniert, ist gefunden in dieser Frage :

def flatten(x):
    result = []
    for el in x:
        if hasattr(el, "__iter__") and not isinstance(el, basestring):
            result.extend(flatten(el))
        else:
            result.append(el)
    return result

flatten(L)

Ist dies das beste Modell? Habe ich etwas übersehen? Gibt es Probleme?

5voto

Shreyas Punkte 1124

Ich bin nicht alle bereits verfügbaren Antworten durchgegangen, aber hier ist ein Einzeiler, den ich mir ausgedacht habe, in Anlehnung an die Art und Weise, wie Lisp die ersten und restlichen Listen verarbeitet

def flatten(l): return flatten(l[0]) + (flatten(l[1:]) if len(l) > 1 else []) if type(l) is list else [l]

Hier ein einfacher und ein nicht ganz so einfacher Fall -

>>> flatten([1,[2,3],4])
[1, 2, 3, 4]

>>> flatten([1, [2, 3], 4, [5, [6, {'name': 'some_name', 'age':30}, 7]], [8, 9, [10, [11, [12, [13, {'some', 'set'}, 14, [15, 'some_string'], 16], 17, 18], 19], 20], 21, 22, [23, 24], 25], 26, 27, 28, 29, 30])
[1, 2, 3, 4, 5, 6, {'age': 30, 'name': 'some_name'}, 7, 8, 9, 10, 11, 12, 13, set(['set', 'some']), 14, 15, 'some_string', 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]
>>>

3voto

ADR Punkte 1191

Verwenden Sie einfach eine funcy Bibliothek: pip install funcy

import funcy

funcy.flatten([[[[1, 1], 1], 2], 3]) # returns generator
funcy.lflatten([[[[1, 1], 1], 2], 3]) # returns list

3voto

diligar Punkte 393

Ich bin mir nicht sicher, ob das unbedingt schneller oder effektiver ist, aber ich mache es so:

def flatten(lst):
    return eval('[' + str(lst).replace('[', '').replace(']', '') + ']')

L = [[[1, 2, 3], [4, 5]], 6]
print(flatten(L))

El flatten Funktion verwandelt die Liste in eine Zeichenkette, entfernt die alle der eckigen Klammern, bringt eckige Klammern wieder an den Enden an und verwandelt sie wieder in eine Liste.

Obwohl, wenn Sie wüssten, dass Sie eckige Klammern in Ihrer Liste in Zeichenketten haben würden, wie [[1, 2], "[3, 4] and [5]"] müssten Sie etwas anderes tun.

3voto

Keine Rekursion oder verschachtelte Schleifen. Ein paar Zeilen. Gut formatiert und leicht zu lesen:

def flatten_deep(arr: list):
    """ Flattens arbitrarily-nested list `arr` into single-dimensional. """

    while arr:
        if isinstance(arr[0], list):  # Checks whether first element is a list
            arr = arr[0] + arr[1:]  # If so, flattens that first element one level
        else:
            yield arr.pop(0)  # Otherwise yield as part of the flat array

flatten_deep(L)

Aus meinem eigenen Code unter https://github.com/jorgeorpinel/flatten_nested_lists/blob/master/flatten.py

2voto

Leo wahyd Punkte 197

Ich bin mir bewusst, dass es bereits viele großartige Antworten gibt, aber ich wollte eine Antwort hinzufügen, die die funktionale Programmiermethode zur Lösung der Frage verwendet. In dieser Antwort benutze ich die doppelte Rekursion:

def flatten_list(seq):
    if not seq:
        return []
    elif isinstance(seq[0],list):
        return (flatten_list(seq[0])+flatten_list(seq[1:]))
    else:
        return [seq[0]]+flatten_list(seq[1:])

print(flatten_list([1,2,[3,[4],5],[6,7]]))

Ausgabe:

[1, 2, 3, 4, 5, 6, 7]

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X