Antworten:
Sie haben es bereits: A if test else B
ist ein gültiger Python-Ausdruck. Das einzige Problem mit Ihrem Diktatverständnis, wie gezeigt, besteht darin, dass die Stelle für einen Ausdruck in einem Diktatverständnis zwei Ausdrücke haben muss, die durch einen Doppelpunkt getrennt sind:
{ (some_key if condition else default_key):(something_if_true if condition
else something_if_false) for key, value in dict_.items() }
Die letzte if
Klausel fungiert als Filter, der sich vom bedingten Ausdruck unterscheidet.
{(a if condition else b): value for key, value in dict.items()}
wird funktionieren.
@ Marcins Antwort deckt alles ab, aber für den Fall, dass jemand ein aktuelles Beispiel sehen möchte, füge ich unten zwei hinzu:
Angenommen, Sie haben das folgende Mengenwörterbuch
d = {'key1': {'a', 'b', 'c'}, 'key2': {'foo', 'bar'}, 'key3': {'so', 'sad'}}
und Sie möchten ein neues Wörterbuch erstellen, dessen Schlüssel angeben, ob die Zeichenfolge 'a'
in den Werten enthalten ist oder nicht
dout = {"a_in_values_of_{}".format(k) if 'a' in v else "a_not_in_values_of_{}".format(k): v for k, v in d.items()}
was ergibt
{'a_in_values_of_key1': {'a', 'b', 'c'},
'a_not_in_values_of_key2': {'bar', 'foo'},
'a_not_in_values_of_key3': {'sad', 'so'}}
Nehmen wir nun an, Sie haben zwei Wörterbücher wie dieses
d1 = {'bad_key1': {'a', 'b', 'c'}, 'bad_key2': {'foo', 'bar'}, 'bad_key3': {'so', 'sad'}}
d2 = {'good_key1': {'foo', 'bar', 'xyz'}, 'good_key2': {'a', 'b', 'c'}}
und Sie möchten die Schlüssel d1
durch die Schlüssel ersetzen. d2
Wenn die jeweiligen Werte identisch sind, können Sie dies tun
# here we assume that the values in d2 are unique
# Python 2
dout2 = {d2.keys()[d2.values().index(v1)] if v1 in d2.values() else k1: v1 for k1, v1 in d1.items()}
# Python 3
dout2 = {list(d2.keys())[list(d2.values()).index(v1)] if v1 in d2.values() else k1: v1 for k1, v1 in d1.items()}
was gibt
{'bad_key2': {'bar', 'foo'},
'bad_key3': {'sad', 'so'},
'good_key2': {'a', 'b', 'c'}}
d1
, d2
erhalte ichAttributeError: 'dict_values' object has no attribute 'index'
Falls Sie unterschiedliche Bedingungen für die Bewertung von Schlüsseln und Werten haben, ist die Antwort von @ Marcin der richtige Weg.
Wenn Sie die gleiche Bedingung für Schlüssel und Werte haben, ist es besser, wenn Sie (Schlüssel, Wert) -Tupel in einem Generatorausdruck erstellen, der Folgendes eingibt dict()
:
dict((modify_k(k), modify_v(v)) if condition else (k, v) for k, v in dct.items())
Es ist einfacher zu lesen und die Bedingung wird nur einmal pro Schlüsselwert bewertet.
Beispiel mit dem Ausleihen von @ Clebs Set-Wörterbuch:
d = {'key1': {'a', 'b', 'c'}, 'key2': {'foo', 'bar'}, 'key3': {'so', 'sad'}}
Angenommen , Sie nur Suffix wollen keys
mit a
in seine value
und Sie wollen , dass die value
mit der Länge des Satzes in einem solchen Fall ersetzt. Andernfalls sollte das Schlüssel-Wert-Paar unverändert bleiben.
dict((f"{k}_a", len(v)) if "a" in v else (k, v) for k, v in d.items())
# {'key1_a': 3, 'key2': {'bar', 'foo'}, 'key3': {'sad', 'so'}}
Ein weiteres Beispiel für die Verwendung von if / else im Wörterbuchverständnis
Ich arbeite an einer Dateneingabe-Desktop-Anwendung für meine eigene Büroarbeit, und es ist üblich, dass eine solche Dateneingabe-Anwendung alle Einträge vom Eingabe-Widget abruft und sie zur weiteren Verarbeitung wie Validierung oder Bearbeitung, die wir zurückgeben müssen, in ein Wörterbuch kopiert ausgewählte Daten aus der Datei zurück zu Eintrags-Widgets usw.
Die erste Runde mit traditioneller Codierung (8 Zeilen):
entries = {'name': 'Material Name', 'maxt': 'Max Working Temperature', 'ther': {100: 1.1, 200: 1.2}}
a_dic, b_dic = {}, {}
for field, value in entries.items():
if field == 'ther':
for k,v in value.items():
b_dic[k] = v
a_dic[field] = b_dic
else:
a_dic[field] = value
print(a_dic)
“ {'name': 'Material Name', 'maxt': 'Max Working Temperature', 'ther': {100: 1.1, 200: 1.2}}”
Zweite Runde Ich habe versucht, das Wörterbuchverständnis zu verwenden, aber die Schleife ist immer noch da (6 Zeilen):
entries = {'name': 'Material Name', 'maxt': 'Max Working Temperature', 'ther': {100: 1.1, 200: 1.2}}
for field, value in entries.items():
if field == 'ther':
b_dic = {k:v for k,v in value.items()}
a_dic[field] = b_dic
else:
a_dic[field] = value
print(a_dic)
“ {'name': 'Material Name', 'maxt': 'Max Working Temperature', 'ther': {100: 1.1, 200: 1.2}}”
Schließlich mit einer einzeiligen Wörterbuchverständniserklärung (1 Zeile):
entries = {'name': 'Material Name', 'maxt': 'Max Working Temperature', 'ther': {100: 1.1, 200: 1.2}}
a_dic = {field:{k:v for k,v in value.items()} if field == 'ther'
else value for field, value in entries.items()}
print(a_dic)
“ {'name': 'Material Name', 'maxt': 'Max Working Temperature', 'ther': {100: 1.1, 200: 1.2}}”
Ich benutze Python 3.8.3
dict
besteht a auskey:value
Elementen, Sie bauen keindict
hier, sondern einset
(siehe Set-Literale ).