Ich habe ein Wörterbuch:

classes_dictionary = {'/m/09x0r': 'Speech', '/m/03qc9zr': 'Screaming'}

Und eine Liste:

labels_list = ['/m/03k3r', '/m/04rlf', '/m/07q5rw0', '/m/09x0r', '/m/0jbk']

labels_list enthält immer mindestens ein Element, das ein Schlüssel von classes_dictionary ist. Ich möchte herausfinden, welche Klassen die mit der geringsten Rechenkomplexität sind. In diesem Beispiel wird '/m/09x0r' in 'Speech' übersetzt. meine Lösung:

class_str = list()
for k in labels_list:
    print(k)
    if k in self.classes_dictionary:
        class_str.append(self.classes_dictionary[k])

Es macht mir nichts aus, wenn die Ausgabe eine Liste oder ein anderer Typ ist. Für die Allgemeinheit der Frage gehe ich auch davon aus, dass nur ein einziges Element von labels_list ein Schlüssel ist, obwohl die beste Antwort beide Fälle berücksichtigen kann.

Gibt es eine effizientere Möglichkeit, dies umzusetzen? Ich frage beide nach Effizienz der Implementierung

3
havakok 19 Feb. 2020 im 14:40

6 Antworten

Beste Antwort

Verwenden eines Listenverständnisses:

>>> [classes_dictionary[k] for k in labels_list if k in classes_dictionary]
['Speech']

Wenn nur eine Übereinstimmung erwartet wird, können Sie next mit einem Generatorausdruck, um die Suche zu beenden, sobald sie gefunden wurde:

>>> next(classes_dictionary[k] for k in labels_list if k in classes_dictionary)
'Speech'
1
kaya3 19 Feb. 2020 im 13:01

Um effizient zu sein, geben Sie das Diktat ein.

#YOUR CODE
if k in self.classes_dictionary:
    #do_job

#More efficient
try:
    self.classes_dictionary[k]
    #do_job
except:
    #Key not in dict
    pass
0
Wonka 19 Feb. 2020 im 11:47

Sie können get() verwenden und prüfen, ob der zurückgegebene Wert nicht None ist, anstatt zu prüfen, ob der Schlüssel im Diktat vorhanden ist (obwohl es sich um eine O (1) -Operation handelt). Wenn Sie wissen, dass es nur ein Wert ist, addieren Sie break

class_str = []
for k in labels_list:
    value = classes_dictionary.get(k)
    if value:
        class_str.append(value)

Wenn Sie Python 3.8 verwenden, können Sie Zuweisungsausdrücke verwenden, die ausgewertet werden classes_dictionary.get(x) nur einmal

class_str = [y for x in labels_list if (y := classes_dictionary.get(x)) is not None]
1
Guy 19 Feb. 2020 im 12:56

Wenn labels_list stattdessen ein Satz ist, können Sie möglicherweise die Leistung beeinträchtigen. Verwenden Sie die Schnittmenge von Set- und Wörterbuchschlüsseln:

classes_dictionary = {'/m/09x0r': 'Speech', '/m/03qc9zr': 'Screaming'}
labels_list= set(['/m/03k3r', '/m/04rlf', '/m/07q5rw0', '/m/09x0r', '/m/0jbk'])

[classes_dictionary[k] for k in labels_list & classes_dictionary.keys()]
0
busybear 19 Feb. 2020 im 11:58

Derzeit besteht Ihre label_list aus einer Zeichenfolge. Es scheint, dass es eine Liste von 5 Zeichenfolgen sein sollte. Du brauchst dich nicht. vor classes_dictionary:

class_str = list()
for k in labels_list:
  print(k)
  if k in classes_dictionary:
    class_str.append(classes_dictionary[k])
0
GLarose 19 Feb. 2020 im 11:52

Sie können den Schnittpunkt der Diktatschlüssel mit den Elementen aus labels_list in einem Listenverständnis verwenden:

class_str = [classes_dictionary[e] for e in set(classes_dictionary).intersection(labels_list)]

Ausgabe:

['Speech']
0
kederrac 19 Feb. 2020 im 12:59