LIst Verständnis: Referenzen auf die Komponenten

8

Zusammenfassend: Ich muss ein List Comprehension schreiben, in dem ich auf eine Liste verweise, die durch das List Comprehension erstellt wird.

Dies ist vielleicht nicht unbedingt etwas, was Sie jeden Tag tun müssen, aber ich denke auch nicht, dass es ungewöhnlich ist.

Vielleicht gibt es hier keine Antwort - trotzdem, bitte sag mir nicht, dass ich eine für Schleife benutzen soll. Das mag stimmen, aber es ist nicht hilfreich. Der Grund liegt in der Problemdomäne: Diese Codezeile ist Teil eines ETL-Moduls, daher ist die Performance relevant, und so muss vermieden werden, einen temporären Container zu erstellen - daher möchte ich diesen Schritt in einem L / C-Code codieren. Wenn hier eine for-Schleife funktionieren würde, würde ich nur eine codieren.

In jedem Fall kann ich dieses bestimmte Listenverständnis nicht schreiben. Der Grund: Der Ausdruck, den ich schreiben muss, hat folgende Form:

%Vor%

In diesem Pseudocode bezieht sich "this_list" auf die Liste, die durch Auswertung dieses Listenverständnisses erstellt wurde. Und deshalb stecke ich fest - weil this_list erst aufgebaut wird, wenn mein Listenverständnis ausgewertet ist, und weil diese Liste noch nicht zu dem Zeitpunkt erstellt wurde, zu dem ich mich darauf beziehen muss, weiß ich nicht, wie ich mich darauf beziehen soll es.

Was ich bisher betrachtet habe (und das auf einer oder mehreren falschen Annahmen beruhen könnte, obwohl ich nicht genau weiß wo):

  • hat der Python-Interpreter nicht um diese Liste im Bau zu geben ein Name? Ich denke schon

  • Dieser temporäre Name ist wahrscheinlich vergeben von einer gebundenen Methode zum Erstellen meine Liste ('Summe'?)

  • aber selbst wenn ich mir die Mühe gemacht habe finde diese gebundene Methode und nehme an dass es tatsächlich der temporäre Name ist Wird vom Python-Interpreter verwendet beziehen Sie sich auf die Liste, während sie darunter ist Konstruktion, ich bin mir ziemlich sicher kann nicht auf gebundene Methoden verweisen direkt; Mir ist das nicht bewusst explizite Regel, aber diese Methoden (um zumindest die wenigen, die ich tatsächlich habe angesehen) sind nicht gültig Python Syntax. Ich vermute einen Grund warum ist so, dass wir sie nicht schreiben unser Code.

Das ist also die Kette meiner so genannten Argumentation, und das hat mich dazu gebracht zu schließen oder zumindest zu erraten, dass ich mich in eine Ecke eingeordnet habe. Trotzdem dachte ich, ich sollte dies mit der Community überprüfen, bevor ich mich umdrehte und in eine andere Richtung ging.

    
doug 20.02.2011, 09:55
quelle

4 Antworten

3

Früher gab es eine Möglichkeit, dies mit der undokumentierten Tatsache zu tun, dass der Wert während der Erstellung der Liste in einer lokalen Variablen namens _[1].__self__ gespeichert wurde. Allerdings hörte das Arbeiten in Python 2.7 auf (vielleicht früher, ich habe nicht genau darauf geachtet).

Wenn Sie zuerst eine externe Datenstruktur einrichten, können Sie in einem einzigen Listenverständnis das tun, was Sie wollen. Da all dein Pseudocode anscheinend mit this_list zu tun hattest, um zu sehen, ob jedes s bereits drin war - also ein Mitgliedstest -, habe ich es in ein set namens seen as geändert eine Optimierung (die Prüfung auf Mitgliedschaft in list kann sehr langsam sein, wenn die Liste groß ist). Hier ist, was ich meine:

%Vor%

Wenn Sie nicht auf some_function zugreifen können, können Sie einen Aufruf in Ihrer eigenen Wrapper-Funktion eingeben, die den Rückgabewert zum seen -Satz hinzufügt, bevor Sie ihn zurückgeben.

Auch wenn es kein Listenverständnis wäre, würde ich das Ganze in eine Funktion kapseln, um die Wiederverwendung zu erleichtern:

%Vor%

In beiden Fällen finde ich es seltsam, dass die Liste, die in Ihrem Pseudo-Code erstellt wird, auf den Sie verweisen möchten, nicht aus einer Untermenge von raw_data -Werten besteht, sondern das Ergebnis von some_function auf jedem von Sie - also transformierte Daten - was natürlich die Frage aufwirft, was some_function so macht, dass sein Rückgabewert mit dem Wert eines bestehenden raw_data -Eintrags übereinstimmt.

    
martineau 20.02.2011, 10:34
quelle
2

Ich verstehe nicht, warum Sie das auf einmal machen müssen. Entweder iteriere zuerst die Anfangsdaten, um Duplikate zu eliminieren - oder, noch besser, konvertiere sie in ein set , wie KennyTM suggeriert - dann führe dein Listenverständnis durch.

Beachten Sie, dass selbst wenn Sie auf die "Liste in Bearbeitung" verweisen könnten, Ihr Ansatz trotzdem fehlschlagen würde, weil s sowieso nicht in der Liste ist - das Ergebnis von some_function(s) ist.

    
Daniel Roseman 20.02.2011 10:08
quelle
2

Soweit ich weiß, gibt es keine Möglichkeit, auf ein Listenverständnis zuzugreifen, während es erstellt wird.

Wie KennyTM erwähnt hat (und wenn die Reihenfolge der Einträge nicht relevant ist), können Sie stattdessen ein set verwenden. Wenn Sie mit Python 2.7 / 3.1 und höher arbeiten, erhalten Sie sogar eine Liste von Comprehensions:

%Vor%

Sonst ist eine for -Schleife auch nicht so schlecht (obwohl sie schrecklich skaliert wird)

%Vor%     
Tim Pietzcker 20.02.2011 10:07
quelle
0

Warum tust du nicht einfach: [ some_function(s) for s in set(raw_data) ]

Das sollte tun, was Sie verlangen. Außer wenn Sie die Reihenfolge der vorherigen Liste beibehalten müssen.

    
jammon 20.02.2011 11:59
quelle