2009-03-23 13 views
12

¿Por qué list.index arroja una excepción, en lugar de usar un valor arbitrario (por ejemplo, -1)? ¿Cuál es la idea detrás de esto?Python list.index arroja una excepción cuando no se encuentra el índice

Para mí, parece más limpio tratar con valores especiales, en lugar de excepciones.

EDIT: No me di cuenta -1 es un valor potencialmente válido. Sin embargo, ¿por qué no otra cosa? ¿Qué tal un valor de None?

Respuesta

12

Porque -1 es en sí mismo un índice válido. Podría usar un valor diferente, como None, pero eso no sería útil, que -1 puede ser en otras situaciones (por lo tanto, str.find()), y equivaldría simplemente a la comprobación de errores, que es exactamente para qué sirven las excepciones.

3

En Python, -1 es un índice válido, lo que significa un número desde el final de la lista (en lugar de al principio), por lo que si usted fuera a hacer

idx = mylist.index(someval) 
nextval = mylist[idx+1] 

entonces se obtendría el primer valor de la matriz, en lugar de darse cuenta de que hubo un error. De esta forma puede atrapar la excepción y tratar con ella. Si no desea excepciones, a continuación, sólo comprobar de antemano:

if someval in mylist: 
    idx = mylist.index(someval) 

Editar: En realidad no hay ningún punto en la devolución de ninguno, porque si vas a probar la Nada, que también podría probar si el valor está en la lista como arriba!

6

Bueno, el valor especial en realidad tendría que ser None, porque -1 es un índice válido (es decir, el último elemento de una lista).

puede emular este comportamiento:

idx = l.index(x) if x in l else None 
+2

Siempre y cuando no te importe buscar dos veces en la lista ... –

+2

bueno, es eso o prueba/excepto. – vartec

1

Una idea simple: -1 es perfectamente utilizable como un índice (como lo son otros valores negativos).

8

Para sumar a la respuesta de Devin: Este es un viejo debate entre los valores de devolución especiales frente a las excepciones. Muchos gurús de la programación prefieren una excepción porque, en una excepción, puedo ver toda la stacktrace e inmediatamente inferir lo que está mal.

+1

Esto era lo que me preguntaba: valores especiales de devolución versus excepciones. –

+3

+1: Las excepciones no dependen de que algún valor sea "sagrado". Las excepciones son a menudo más simples de trabajar. –

+0

Las personas exceptiophobic podrían argumentar que 'index' no encontrar un objeto no es un error, y las excepciones solo deberían usarse en los errores. Estoy a favor de las excepciones en este caso. Las excepciones pueden ser más rápidas ya que no tienen que verificar el éxito. Python prefiere excepciones en muchos casos debido a esto. En otras palabras, si 'index' encuentra un objeto, la ejecución continúa sin verificación de condición. Si 'index' no encuentra nada, se lo arroja al bloque catch sin controles. –

1

Es un argumento semántico. Si desea conocer el índice de un elemento, afirma que ya existe en la lista. Si desea saber si existe o no, debe usar in.

+1

... y si alega que existe una excepción es la forma correcta de manejarlo. –

2

Estoy de acuerdo con Devin Jeanpierre, y agregaría que tratar con valores especiales puede parecer bueno en pequeños casos de ejemplo pero (con algunas excepciones notables, por ejemplo NaN en FPU y Null en SQL) no escala casi tan bien . La única vez en que funciona es donde:

  • Has normalmente tiene gran capacidad de procesamiento homogénea anidado (por ejemplo, matemáticas o SQL)
  • Usted no se preocupan por distinguir los tipos de error
  • No te importa donde ocurrió el error
  • Las operaciones son funciones puras, sin efectos secundarios.
  • Si no se puede dar un significado razonable en el nivel superior (por ejemplo, "No hay fila coincidió")
3

Es principalmente para asegurar que los errores son capturados tan pronto como sea posible. Por ejemplo, considere lo siguiente:

l = [1, 2, 3] 
x = l.index("foo") #normally, this will raise an error 
l[x] #However, if line 2 returned None, it would error here 

Se dará cuenta de que un error serían botados en l[x] en lugar de en x = l.index("foo") si el índice volviera Ninguno. En este ejemplo, eso no es realmente un gran problema. Pero imagine que la tercera línea está en un lugar completamente diferente en un programa de un millón de líneas. Esto puede llevar a una pesadilla de depuración.

4

El debate "excepción-contra-error" se debe en parte a la claridad del código. Considere código con un valor de error:

idx = sequence.index(x) 
if idx == ERROR: 
    # do error processing 
else: 
    print '%s occurred at position %s.' % (x, idx) 

El manejo de errores termina metido en el medio de nuestro algoritmo, oscureciendo el flujo del programa. Por otra parte:

try: 
    idx = sequence.index(x) 
    print '%s occurred at position %s.' % (x, idx) 
except IndexError: 
    # do error processing 

En este caso, la cantidad de código es efectivamente el mismo, pero el algoritmo principal es ininterrumpida por tratamiento de errores.

0
def GetListIndex(list, searchString): 
    try: 
     return list.index(searchString) 

    except ValueError: 
     return False 

    except Exception: 
     raise 
Cuestiones relacionadas