Erlang und Ruby bieten Funktionen zum Reduzieren von Arrays. Es scheint so ein einfaches und nützliches Werkzeug zu sein, um einer Sprache etwas hinzuzufügen. Das könnte man machen:
>>> mess = [[1, [2]], 3, [[[4, 5]], 6]]
>>> mess.flatten()
[1, 2, 3, 4, 5, 6]
Oder auch:
>>> import itertools
>>> mess = [[1, [2]], 3, [[[4, 5]], 6]]
>>> list(itertools.flatten(mess))
[1, 2, 3, 4, 5, 6]
Stattdessen muss man sich in Python die Mühe machen, eine Funktion zu schreiben, mit der Arrays von Grund auf abgeflacht werden. Das kommt mir albern vor, Arrays zu verflachen ist so eine gewöhnliche Sache. Es ist, als müsste man eine benutzerdefinierte Funktion schreiben, um zwei Arrays zu verketten.
Ich habe das fruchtlos gegoogelt, also frage ich hier; Gibt es einen bestimmten Grund, warum eine ausgereifte Sprache wie Python 3, die mit hunderttausenden verschiedenen Batterien geliefert wird, keine einfache Methode zum Reduzieren von Arrays bietet? Wurde die Idee, eine solche Funktion aufzunehmen, diskutiert und irgendwann abgelehnt?
quelle
extend
aber Abflachen wäre viel eleganter gewesen. Ich wundere mich jedoch, wenn dieses Muster häufig genug ist, um eine Verflachung in der Standardbibliothek zu rechtfertigen.Antworten:
Vorschläge für eine
flatten
Funktion, die der Standardbibliothek hinzugefügt werden soll, erscheinen von Zeit zu Zeit auf den Mailinglisten von python-dev und python-ideas . Python-Entwickler antworten normalerweise mit den folgenden Punkten:Eine einstufige Reduzierung (Umwandlung einer Iteration von Iterationen in eine einzige Iteration) ist ein trivialer einzeiliger Ausdruck
(x for y in z for x in y)
und befindet sich auf jeden Fall bereits in der Standardbibliothek unter dem Namenitertools.chain.from_iterable
.Was sind die Anwendungsfälle für eine allgemeine mehrstufige Abflachung? Sind diese wirklich überzeugend genug, damit die Funktion zur Standardbibliothek hinzugefügt werden kann?
Wie würde eine universelle mehrstufige Abflachung entscheiden, wann sie abgeflacht werden soll und wann sie in Ruhe gelassen werden soll? Sie könnten denken, dass eine Regel wie "Alles reduzieren, was die iterable Schnittstelle unterstützt" funktionieren würde, aber das würde zu einer Endlosschleife für führen
flatten('a')
.Siehe zum Beispiel Raymond Hettinger :
quelle
flatten
Funktion definiert werden kann alslambda z: [x for y in z for x in y]
.flatten
Methode haben. Die Implementierung dieser Methode sollteflatten
ihre Unterkomponente rekursiv aufrufen , wenn das Objekt ein zusammengesetztes Objekt ist. Leider ist AFAIK nicht jeder Wert ein Objekt in Python. In Ruby sollte es allerdings funktionieren.Es kommt mit einer solchen Methode, aber es nennt es nicht platt. Es heißt " Kette ". Es gibt einen Iterator zurück, den Sie dann mit der Funktion list () wieder in eine Liste umwandeln müssen. Wenn Sie kein * verwenden möchten, können Sie die zweite "from_iterator" -Version verwenden. In Python 3 funktioniert es genauso . Es schlägt fehl, wenn die Listeneingabe keine Liste von Listen ist.
Es gab einmal eine Abflachungsmethode im Modul compiler.ast, die jedoch in 2.6 veraltet war und in 3.0 entfernt wurde. Die willkürliche Tiefenrekursion, die für beliebig verschachtelte Listen erforderlich ist, funktioniert mit der konservativen maximalen Rekursionstiefe von Python nicht gut. Die Gründe für das Entfernen des Compilers waren größtenteils darauf zurückzuführen, dass es sich um ein Chaos handelte . Der Compiler wurde in ast verwandelt, aber die Abflachung blieb zurück.
Beliebige Tiefe kann mit numpy's Arrays und der Abflachung dieser Bibliothek erreicht werden.
quelle
chain.from_iterator
Funktion kann, wie Sie sagten, nur zum Reduzieren zweidimensionaler Listen verwendet werden. Eine tatsächliche Abflachungsfunktion, die beliebige Mengen verschachtelter Listen akzeptiert und eine eindimensionale Liste zurückgibt, wäre in vielen Fällen (zumindest meiner Meinung nach) immer noch... vielleicht, weil es gar nicht so schwer ist, selbst einen zu schreiben
... und dann mach alles flach was du willst :)
quelle