2015-05-08 2 views
5

Betrachten Sie den folgenden Code ein:Kann man Listenverständnis-Derivate in seinen Methoden verwenden?

a = [... for i in input] 
i = a.index(f(a)) 

Ich frage mich, ob ich in der Lage sein könnte, einen Einzeiler zu tun. Offensichtlicher Versuch ist:

i = [... for i in input].index(f([... for i in input])) 

Aber diese Lösung erfordert Liste zweimal generiert werden. nicht so offensichtliche Versuch ist:

i = [ a.index(f(a)) for a in [[... for i in input],] ] 

Welche der Trick funktioniert, aber macht Code wirklich seltsam.

Dies führt mich zu der Idee, dass es wahrscheinlich die Möglichkeit gibt, die Liste zu verwenden, die durch das Listenverständnis erzeugt wird, in ihrer eigenen Methodenaufruf. Etwas wie (beide funktionieren nicht, offensichtlich):

i = [... for i in input].index(f(_)) 
# or 
i = [... for i in input].index(f(self)) 

Kann es getan werden?

+5

Warum möchten Sie die Lesbarkeit ausschalten? :) –

+3

Was macht f()? Möchten Sie einfach den Index eines bestimmten Listenelements erhalten? – ODiogoSilva

+1

Sie könnten ein Lambda erstellen und es sofort mit Ihrem Verständnis aufrufen: 'i = (Lambda x: x.index (f (x)) ([... für i in Eingabe])' Aber das ist Häresie. Auch, don Benennen Sie eine iterierbare Eingabe, die die eingebaute Eingabefunktion maskiert – Shashank

Antwort

2

Eine Möglichkeit, dass die Liste Verständnis vermeidet Wiederholung ist eine anonyme Funktion zu erstellen und es direkt (nicht getestet) Aufruf:

i = (lambda a: a.index(f(a)))([... for i in input]) 

Dies ist immer noch ein bisschen hässlich, aber. Ihr erstes Beispiel, das die temporäre Variable a verwendet, ist viel klarer. Das Schreiben von Einzeilern als Übung macht Spaß, ist aber normalerweise nicht der beste Weg, um wartbaren Code zu schreiben.

6

Während Sie eine Rekursionsaufgabe ausführen, können Sie Ihre Funktion basierend auf Ihrer Funktion mit einem Listenverständnis oder einem Generatorausdruck kombinieren.

zum Beispiel betrachten Sie den folgenden Code:

>>> next(i for i,j in enumerate(a) if j.startswith('a')) 
3 

So its all auf der Grundlage Ihrer Funktion, dass, wie Sie seine Struktur setzen kann im Bereich:

>>> f=lambda x:next(i for i in x if i.startswith('a')) 
>>> 
>>> a=['df','sr','t','aaf','ar','trf'] 
>>> a.index(f(a)) 
3 

Sie können enumerate mit wie folgt mischen ein List-Verständnis oder ein Generator-Ausdruck, und wenden Sie einige Änderungen darauf an und verwenden Sie Python-Tools basierend auf Ihren Bedürfnissen (in diesem Fall haben wir enumerate verwendet).

+0

soweit ich sehen kann - Ihre Lösung funktioniert nur für die einfache Indizierung Aufgaben; es ist jedoch nicht allgemein anwendbar. Das einfachste Beispiel, das ich mir vorstellen kann, ist, wenn f = min (mylist), also könnten wir den Index des minimalen Elements vom Generator abrufen. Es scheint mir nicht offensichtlich, wie Sie die Lösung für einen solchen Fall nutzen könnten. Und auch, wie ich im Kommentar höher erwähnte - mein Interesse ist, ob es eine eingebaute Variable wie "_" gibt, nur dass man mir erlauben würde, auf Ergebnisse zuzugreifen, die nicht vorheriger Ausdruck, sondern vorheriger berechneter Ausdruck innerhalb des Ausdrucks waren. –