Liste und erfassen, überprüfen, wenn das Einzelteil ist einzigartig
Ich bin versucht zu schreiben, eine Liste Verständnis statement, das nur ein Element hinzufügen, wenn Sie derzeit nicht in der Liste enthalten. Gibt es eine Möglichkeit zu prüfen, die aktuelle Elemente in der Liste, die gerade aufgebaut wird? Hier ist ein kurzes Beispiel:
Eingang
{
"Stefan" : ["running", "engineering", "dancing"],
"Bob" : ["dancing", "art", "theatre"],
"Julia" : ["running", "music", "art"]
}
Ausgabe
["running", "engineering", "dancing", "art", "theatre", "music"]
Code ohne Verwendung einer Liste Verständnis
output = []
for name, hobbies in input.items():
for hobby in hobbies:
if hobby not in output:
output.append(hobby)
Mein Versuch
[hobby for name, hobbies in input.items() for hobby in hobbies if hobby not in ???]
- Erwägen Sie die Verwendung ein, anstatt, wie es eliminiert Duplikate automatisch für Sie.
- Ich könnte die Ausgabe der Liste Verständnis in der set () - Konstruktor, aber ich Frage mich ob es einen Weg gibt, dies zu tun, nur mit list comprehension
- Sie missbrauchen könnte
yield from
in Python ist3.3+ zu vermeiden, double-loop:set([(yield from x) for x in d.values()])
. Beachten Sie, dass diess=set((yield from x) for x in d.values())
Erträge fast die gewünschte Ausgabe... es enthält eine zusätzlicheNone
, die Sie entfernen müssen, sos.discard(None)
. (Ich glaube, es gibt schon eine Frage zu diesem Unterschied im Verhalten zwischen gen exps und Liste-Verstehens).
InformationsquelleAutor Stefan Bossbaly | 2015-05-19
Schreibe einen Kommentar Antworten abbrechen
Du musst angemeldet sein, um einen Kommentar abzugeben.
Können Sie
set
- und set-comprehension:Als m.wasowski erwähnt, wir verwenden nicht die
name
hier, so können wiritem.values()
statt:Wenn Sie wirklich brauchen, eine Liste als Ergebnis, Sie können dies tun (aber beachten Sie, dass in der Regel können Sie arbeiten mit sets ohne problem):
input.values()
wenn Sie kümmern sich nicht um Namenhobbies
sind definiert als die Listen von Hobbys, die ininput.values()
(d.h. eine Liste von Listen von Hobbys). Dann werden diese Listen iteriert durch diefor hobby in hobbies
- hierhobbies
ist eine Nutzung derhobbies
definiert durchhobbies in input.values()
. Die zweitehobby
ist daher definiert als jeder hobby in jedemhobbies
Liste (one by one). Die erstenhobby
ist dann eine Verwendung solcher definiert Hobbys, und jedes solches hobby ist Hinzugefügt, um die Ergebnismenge. Damit jedes hobby ist in der Folge einmal (denn es ist ein set). Ist es klarer jetzt? Ich hoffe, ich habe nicht noch schlimmer machen.fun
vonhobby
?{fun(hobby) for hobbies in input.values() for fun(hobby) in hobbies}
. Läuft inSyntaxError
mit diesem Ansatz. Und wenn nicht, gibt es eine alternative?Als diese Antwort - Idee: Sie können eine Einzigartigkeit filter:
und rufen mit:
Ich würde implementieren, die Einzigartigkeit filter getrennt, da eine design-Regel sagt "verschiedene Dinge behandelt werden sollten, die durch verschiedene Klassen/Methoden/Komponenten/was auch immer". Darüber hinaus können Sie einfach wiederverwenden Sie diese Methode, wenn nötig.
Ein weiterer Vorteil ist - wie ist geschrieben in der verlinkte Antwort -, dass die um der Elemente wird beibehalten. Für einige Anwendungen notwendig sein könnten.
if x not in seen and seen.add(x) is None
seen.add
ist es möglich (im Allgemeinen, nicht in diesem Fall), dass dieseen.add
geändert wird zwischen zwei Anrufe. Python hat damit führen Sie eine weitere Suche.not (seen.add(x) is None)
für den zweiten Teil sowieso und (b) kann man kaum sagen, das ist vorzeitige - Optimierung, da dies eine utility-Funktion. 😉sets und dictionaries sind deine Freunde hier:
data
ist ein normales Wörterbuch, Sie die resultierende Reihenfolge der Aufrufdata.values()
ist willkürlich. Dadurch ist die Reihenfolge derkeys()
imOrderedDict
betrachtet werden teilweise willkürlich als gut. Die Listen sind zufällig sortiert (in deinem Fall die Reihenfolge der Listen wurden diejenigen von: Bob, Stefan, Julia), aber Ihre Elemente' Aufträge erhalten. Aufgrund von überschneidungen kann dies dazu führen, ganz andere Aufträge.Wenn Sie wirklich, wirklich wollen, eine listcomp und nur eine Liste-comp, die Sie tun können,
Hier
s
ist das Ergebnis einer Nebenwirkung undd
ist Ihre original-Wörterbuch. Der eindeutige Vorteil hier ist, dass bewahren Sie die Reihenfolge, im Gegensatz zu den meisten anderen Antworten hier.itertools.chain.from_iterable
- wie ich in meiner Antwortitertools
Antwort. 3. Das ist reines python ohne Importe. Deine Antwort ist gut, kein ZweifelGibt es einen anderen Weg dies zu schreiben, dass ist ein bisschen mehr beschreiben, was Sie eigentlich tun, und nicht einen verschachtelten (Doppel -
for
) Verständnis:Diese wird noch schöner, wenn Sie würden repräsentieren die Eingabe, um mehr konzeptionell solide sind, D. H. die Nutzung setzt sich für die Hobbys der jeweiligen person (seit es sollte keine Wiederholungen gibt):
Einer list comprehension ist nicht gut geeignet für dieses problem. Ich denke, ein set Verständnis wäre besser, aber da war schon in einer anderen Antwort, ich zeige einen Weg, dieses problem zu lösen mit einem kompakten one-liner:
Andere interessante Lösung mit dem bitweisen oder-operator dient als union-operator für Mengen:
Oder (unbeabsichtigtes Wortspiel, ich schwöre), anstelle der Verwendung der bitweisen oder-operator, verwenden Sie einfach
set.union
übergeben und ausgepackt festlegen-Zuordnung der Werte. Keine Notwendigkeit zu importierenor_
undreduce
! Diese Idee ist inspiriert von Thijs van Dien Antwort.Satz:
Wie wäre es damit:
Oder mehr schön:
können Sie die
list
Funktion list_ wielist(list_)
um eine Liste statt einen Satz.