en y función de índice de la lista

Estoy tratando de entender el funcionamiento interno del comando in y el index() de la estructura de datos de la lista.

Cuando yo digo:

 if something not in some_list : print "do something" 

¿Está atravesando la lista completa internamente, de forma similar a un bucle for o utiliza mejores enfoques como hashtables etc.?

También el index() en las listas, da un error si el elemento no está presente en la lista. ¿El trabajo de ambos in e index() el mismo? Si el index() es mejor, ¿es posible detectar el error cuando un elemento no está presente y, si es posible, es una buena progtwigción?

¡Buena pregunta! Sí, ambos métodos que mencionas repetirán la lista, necesariamente. Python no usa tablas hash para las listas porque no hay restricción de que los elementos de la lista sean hashable.

Si conoce la notación “Big O” , la estructura de datos de la list está diseñada para el acceso O (1) buscando un índice conocido, por ejemplo, my_list[13] . Es O (n) para la prueba de membresía.

Hay otras estructuras de datos que están optimizadas para la velocidad O (1) para las pruebas de membresía (es decir, __contains__ ), a saber, set y dict . Estos se implementan con tablas hash .

Este es un ejemplo de cómo puede usar IPython para verificar la complejidad de tiempo de los conjuntos y listas, para confirmar estas afirmaciones:

 In [1]: short_list, long_list = range(1000), range(10000) In [2]: timeit 'potato' not in short_list 10000 loops, best of 3: 40.9 µs per loop In [3]: timeit 'potato' not in long_list 1000 loops, best of 3: 440 µs per loop In [4]: small_set, big_set = set(short_list), set(long_list) In [5]: timeit 'potato' not in small_set 10000000 loops, best of 3: 72.9 ns per loop In [6]: timeit 'potato' not in big_set 10000000 loops, best of 3: 84.5 ns per loop 

Para las listas, ambos métodos ( in e index() ) se repiten sobre la lista para verificar el elemento que está buscando, desafortunadamente. Detendrán la iteración tan pronto como se conozca el resultado de la prueba de membresía, lo que significa que se repetirán hasta el final si no se encuentra el elemento.

Por lo que sé, si debe trabajar con listas, not in construcción es el más Python y con el que debería ir (pero debe volcar esos paréntesis innecesarios).

Si no necesita utilizar específicamente una lista, el tipo de conjunto incorporado a menudo puede funcionar en su lugar. El conjunto es una estructura de datos similar a la lista, pero utiliza un algoritmo de hash para probar la presencia de un elemento, por lo que si está haciendo mucho de ese tipo de trabajo, puede considerar cambiar. Sin embargo, lea los documentos a los que he vinculado, porque los conjuntos no están ordenados, por lo que no admiten cosas como el corte o la indexación.

Sí, puede planificar los momentos en que el elemento que está verificando no está presente en su estructura de datos. Estás buscando un Bloque de Prueba / Excepto :

 example_list = [1,2,3] try: index_of_4 = example_list.index(4) except ValueError: print("Oops! 4 wasn't in the list!") 

Cuando sepa que pueden producirse excepciones en su progtwig, puede envolver el código ofensivo en un bloque como este para capturar con gracia y recuperarse de las excepciones. De hecho, es una buena práctica de progtwigción recuperarse de errores y excepciones tan bien como sea posible, incluso si eso significa simplemente imprimir un mensaje de error y salir.