Te recomendamos que revises esta resolución en un ambiente controlado antes de enviarlo a producción, saludos.
Solución:
Ya lo tienes: A if test else B
es una expresión de Python válida. El único problema con su comprensión de dictado como se muestra es que el lugar para una expresión en una comprensión de dictado debe tener dos expresiones, separadas por dos puntos:
(some_key if condition else default_key):(something_if_true if condition
else something_if_false) for key, value in dict_.items()
El final if
cláusula actúa como un filtro, que es diferente de tener la expresión condicional.
La respuesta de @Marcin lo cubre todo, pero en caso de que alguien quiera ver un ejemplo real, agrego dos a continuación:
Digamos que tienes el siguiente diccionario de conjuntos
d = 'key1': 'a', 'b', 'c', 'key2': 'foo', 'bar', 'key3': 'so', 'sad'
y desea crear un nuevo diccionario cuyo keys indicar si el string 'a'
está contenido en los valores o no, puede utilizar
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()
cuyos rendimientos
'a_in_values_of_key1': 'a', 'b', 'c',
'a_not_in_values_of_key2': 'bar', 'foo',
'a_not_in_values_of_key3': 'sad', 'so'
Ahora supongamos que tiene dos diccionarios como este
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'
y desea reemplazar el keys en d1
por el keys de d2
si los valores respectivos son idénticos, podrías hacer
# 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()
lo que da
'bad_key2': 'bar', 'foo',
'bad_key3': 'sad', 'so',
'good_key2': 'a', 'b', 'c'
en caso de que tengas diferente condiciones evaluar para keys y valores, la respuesta de @Marcin es el camino a seguir.
si tienes el mismo condición por keys y valores, es mejor que construyas (key, valor) tuplas en una expresión generadora que alimenta dict()
:
dict((modify_k(k), modify_v(v)) if condition else (k, v) for k, v in dct.items())
Es más fácil de leer y la condición solo se evalúa una vez por key, valor.
Ejemplo con el préstamo del diccionario de conjuntos de @Cleb:
d = 'key1': 'a', 'b', 'c', 'key2': 'foo', 'bar', 'key3': 'so', 'sad'
Suponga que desea sufijo solamente keys
con a
en su value
y tu quieres el value
reemplazado con la longitud del conjunto en tal caso. De lo contrario, el keyEl par de valores debe permanecer sin cambios.
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'