Python: Asignar Valor si No Existe Ninguno


Soy un programador RoR nuevo en Python. Estoy tratando de encontrar la sintaxis que me permita establecer una variable a un valor específico solo si no fue asignada previamente. Básicamente quiero:

# only if var1 has not been previously assigned

var1 = 4

Author: Spencer, 2011-09-07

6 answers

Este es un estilo de programación muy diferente, pero siempre intento reescribir cosas que parecían

bar = None
if foo():
    bar = "Baz"

if bar is None:
    bar = "Quux"

En solo:

if foo():
    bar = "Baz"
else:
    bar = "Quux"

Es decir, me esfuerzo por evitar una situación en la que algunas rutas de código definen variables pero otras no. En mi código, nunca hay una ruta que cause una ambigüedad del conjunto de variables definidas (De hecho, generalmente lo llevo un paso más allá y me aseguro de que los tipos sean los mismos independientemente de la ruta de código). Puede ser sólo un asunto de gusto personal, pero encuentro este patrón, aunque un poco menos obvio cuando lo estoy escribiendo, mucho más fácil de entender cuando lo estoy leyendo más tarde.

 21
Author: SingleNegationElimination,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-09-07 18:24:38

Debe inicializar las variables a None y luego comprobarlo:

var1 = None
if var1 is None:
    var1 = 4

Que se puede escribir en una línea como:

var1 = 4 if var1 is None else var1

O usando un atajo (pero se recomienda cotejar con Ninguno)

var1 = var1 or 4

Alternativamente, si no tiene nada asignado a la variable, el nombre de la variable no existe y, por lo tanto, usar eso más tarde elevará NameError, y también puede usar ese conocimiento para hacer algo como esto

try:
    var1
except NameError:
    var1 = 4

Pero yo desaconsejaría eso.

 66
Author: Anurag Uniyal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-05-20 16:22:56
var1 = var1 or 4

El único problema que esto podría tener es que si var1 es un valor falsey, como False o 0 o [], elegirá 4 en su lugar. Eso podría ser un problema.

 20
Author: ubadub,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-03-29 20:15:09

También vengo de Ruby, así que me encanta la sintaxis foo ||= 7.

Esto es lo más cercano que puedo encontrar.

foo = foo if 'foo' in vars() else 7

He visto a la gente hacer esto por un dictado:

try:
    foo['bar']
except KeyError:
    foo['bar'] = 7

Upadate: Sin embargo, recientemente encontré esta gema:

foo['bar'] = foo.get('bar', 7)

Si te gusta eso, entonces para una variable regular podrías hacer algo como esto:

vars()['foo'] = vars().get('foo', 7)
 11
Author: l__flex__l,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-10 10:00:33

La respuesta de IfLoop (y el comentario de MatToufoutu) funcionan muy bien para variables independientes, pero quería proporcionar una respuesta para cualquiera que intente hacer algo similar para entradas individuales en listas, tuplas o diccionarios.

Diccionarios

existing_dict = {"spam": 1, "eggs": 2}
existing_dict["foo"] = existing_dict["foo"] if "foo" in existing_dict else 3

Devuelve {"spam": 1, "eggs": 2, "foo": 3}

Listas

existing_list = ["spam","eggs"]
existing_list = existing_list if len(existing_list)==3 else 
                existing_list + ["foo"]

Devuelve ["spam", "eggs", "foo"]

Tuplas

existing_tuple = ("spam","eggs")
existing_tuple = existing_tuple if len(existing_tuple)==3 else 
                 existing_tuple + ("foo",)

Devuelve ("spam", "eggs", "foo")

(No olvide la coma en ("foo",) para definir un " single" tuple.)

La solución de listas y tuplas será más complicada si desea hacer algo más que verificar la longitud y agregar al final. Sin embargo, esto le da una idea de lo que puede hacer.

 2
Author: Alex P. Miller,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-07-01 15:12:46

Si se refiere a una variable a nivel de módulo, puede usar "globales":

if "var1" not in globals():
    var1 = 4

Pero el lenguaje común de Python es inicializarlo para decir None (asumiendo que no es un valor aceptable) y luego probar con if var1 is not None.

 1
Author: 6502,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-09-07 18:15:44