Tengo un código que se parece a esto:
thing_index = thing_list.index(thing)
otherfunction(thing_list, thing_index)
ok, eso está simplificado, pero entiendes la idea. Es thing
posible que ahora no esté en la lista, en cuyo caso quiero pasar -1 como thing_index
. En otros idiomas, esto es lo que esperaría index()
devolver si no pudiera encontrar el elemento. De hecho arroja un ValueError
.
Yo podría hacer esto:
try:
thing_index = thing_list.index(thing)
except ValueError:
thing_index = -1
otherfunction(thing_list, thing_index)
Pero esto se siente sucio, además de que no sé si se ValueError
podría plantear por alguna otra razón. Se me ocurrió la siguiente solución basada en funciones de generador, pero parece un poco compleja:
thing_index = ( [(i for i in xrange(len(thing_list)) if thing_list[i]==thing)] or [-1] )[0]
¿Existe una forma más limpia de lograr lo mismo? Supongamos que la lista no está ordenada.
thing_index
". - Esto definitivamente no es pitónico. Pasar un valor de token (sin sentido) en caso de que una operación no tenga éxito está mal visto; las excepciones realmente son la forma correcta aquí. Especialmente porquething_list[-1]
es una expresión válida, es decir, la última entrada en la lista.str.find
método que hace exactamente eso: regresa-1
cuando la aguja no se encuentra en el sujeto.str.index()
lanza una excepción si no se encuentra la cadena de búsqueda.Respuestas:
No hay nada "sucio" en el uso de la cláusula try-except. Esta es la forma pitónica.
ValueError
solo se generará con el.index
método, ¡porque es el único código que tiene allí!Para responder al comentario:
en Python, es más fácil pedir perdón que obtener permiso, la filosofía está bien establecida, y no
index
generará este tipo de error para otros problemas. No es que pueda pensar en ninguno.fuente
{}.get(index, '')
más pitónico? Por no hablar de más corto más legible.None
lugar de -1 estaría bien, pero como usted mismo comentó, str.find () devuelve -1, entonces, ¿por qué no debería haber list.find () que haga lo mismo? No estoy de acuerdo con el argumento "pitónico"otherfunction
. Por otro lado, si no está roto, ...Una línea. Sencillo. Sin excepciones.
fuente
for
.indexOf = lambda item,list_ : list_.index(item) if item in list_ else -1 # OR None
El
dict
tipo tiene unaget
función , donde si la clave no existe en el diccionario, el segundo argumentoget
es el valor que debe devolver. De manera similar, haysetdefault
, que devuelve el valor en eldict
si la clave existe; de lo contrario, establece el valor de acuerdo con su parámetro predeterminado y luego devuelve su parámetro predeterminado.Puede extender el
list
tipo para tener ungetindexdefault
método.Que luego podría usarse como:
fuente
No hay nada de malo en el código que usa
ValueError
. Aquí hay otro resumen si desea evitar excepciones:fuente
next()
función existe en Python 2.6+. Pero es fácil de implementar para 2.5, consulte la implementación de la función next () para Python 2.5Este problema es de filosofía del lenguaje. En Java, por ejemplo, siempre ha existido la tradición de que las excepciones sólo deberían utilizarse en "circunstancias excepcionales", es decir, cuando se han producido errores, en lugar de para el control de flujo . Al principio, esto fue por razones de rendimiento, ya que las excepciones de Java eran lentas, pero ahora este se ha convertido en el estilo aceptado.
Por el contrario, Python siempre ha usado excepciones para indicar el flujo normal del programa, como generar un
ValueError
como estamos discutiendo aquí. No hay nada "sucio" en esto en estilo Python y hay muchos más de donde vino eso. Un ejemplo aún más común es laStopIteration
excepción que se genera mediante elnext()
método de un iterador para indicar que no hay más valores.fuente
StopIteration
porque está claramente definido lo que significa la excepción.ValueError
es demasiado genérico.Si lo hace con frecuencia, es mejor que lo elimine en una función de ayuda:
fuente
¿Qué pasa con esto?:
fuente
¿Qué pasa con esto?
En lugar de exponer algo tan dependiente de la implementación como un índice de lista en una interfaz de función, pase la colección y la cosa y deje que otra función se ocupe de los problemas de "prueba de pertenencia". Si se escribe otra función para que sea independiente del tipo de colección, probablemente comenzaría con:
que funcionará si thing_collection es una lista, tupla, conjunto o dict.
Esto posiblemente sea más claro que:
que es el código que ya tiene en otra función.
fuente
¿Qué tal esto?
fuente
Tengo el mismo problema con el método ".index ()" en las listas. No tengo ningún problema con el hecho de que arroja una excepción, pero estoy totalmente en desacuerdo con el hecho de que es un ValueError no descriptivo. Sin embargo, podría entender si hubiera sido un IndexError.
Puedo ver por qué devolver "-1" también sería un problema porque es un índice válido en Python. Pero de manera realista, nunca espero que un método ".index ()" devuelva un número negativo.
Aquí va una línea (vale, es una línea bastante larga ...), recorre la lista exactamente una vez y devuelve "Ninguno" si no se encuentra el elemento. Sería trivial reescribirlo para devolver -1, si así lo desea.
Cómo utilizar:
fuente
No sé por qué debería pensar que está sucio ... ¿por la excepción? si quieres un delineador, aquí está:
pero desaconsejaría su uso; Creo que la solución de Ross Rogers es la mejor, use un objeto para encapsular su comportamiento deseado, no intente llevar el lenguaje al límite a costa de la legibilidad.
fuente
find()
función y estará todo limpio;)Sugeriría:
fuente