iterar Python nested listas de manera eficiente

Estoy trabajando en un proyecto de monitor de tráfico de red en Python. No estoy familiarizado con Python, así que estoy buscando ayuda aquí.

En resumen, estoy revisando el tráfico tanto dentro como fuera, lo escribí de esta manera:

for iter in ('in','out'): netdata = myhttp() print data 

netdata es una lista que consta de listas anidadas, su formato es el siguiente:

 [ [t1,f1], [t2,f2], ...] 

Aquí t representa el momento y f es el flujo. Sin embargo, solo quiero mantener esto en este momento tanto dentro como fuera, me pregunto de alguna manera para obtener un código eficiente.

Después de algunas búsquedas, creo que necesito usar crear una lista de tráfico (2 elementos), luego usar la función zip para iterar ambas listas al mismo tiempo, pero tengo dificultades para escribir una correcta. Dado que mi netdata es una lista muy larga, la eficiencia también es muy importante.

Si hay algo confuso, hágamelo saber, intentaré aclarar. Gracias por la ayuda

Aparte de algunas correcciones menores en su código (las cuestiones planteadas por @Zero Piraeus), su pregunta probablemente fue respondida aquí . Un posible código para recorrer una lista de listas en N grados (un árbol) es el siguiente:

 def traverse(item): try: for i in iter(item): for j in traverse(i): yield j except TypeError: yield item 

Ejemplo:

 l = [1, [2, 3], [4, 5, [[6, 7], 8], 9], 10] print [i for i in traverse(l)] [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 

La clave para hacer que funcione es la recursión y la clave para que funcione de manera eficiente es usar un generador (el yield la palabra clave da una pista). El generador iterará a través de su lista de listas y regresará artículo por elemento, sin necesidad de copiar datos o crear una lista completamente nueva (a menos que consum todo el generador asignando el resultado a una lista, como en mi ejemplo)

El uso de iteradores y generadores puede ser conceptos extraños para comprender (el yield la palabra clave es principalmente). Echa un vistazo a esta gran respuesta para entenderlos completamente.

El código que has mostrado no tiene mucho sentido. Esto es lo que hace:

  • Iterar a través de la secuencia 'in', 'out' , asignando cada una de esas dos cadenas sucesivamente a la variable iter (enmascarando la función incorporada iter() en el proceso) en sus dos pasadas por el bucle.

  • Ignora completamente el valor de iter dentro del bucle.

  • Asigne el resultado de myhttp() a la variable netdata en cada paso a través del bucle.

  • netdata completamente el valor de netdata y, en su lugar, intente imprimir los data variables indefinidos en cada paso a través del bucle.

Es posible, dada la lista anidada que describe, que quiera algo como esto:

 for t, f in myhttp(): print t print f # ... or whatever you want to do with those values. 

Cuando intenté una, la otra respuesta, la función no pudo repetirse, así que la modifiqué para que no retrocediera. Todavía funciona bastante rápido y puede manejar grandes listas anidadas (al menos por lo que puedo ver con mis pruebas). Es una función única de Python 3.

 # Originally by Bruno Polaco def traverse(item, reverse=False): its = [item] #stack of items to-be-processed out = [] # Output (no longer generator) ite = False while len(its) > 0: it = its.pop() try: # Check if item is iterable iter(it) ite = not isinstance(it, str) except TypeError: ite = False if ite: # Do something with it for i in it: its.append(i) else: out.append(it) if not reverse: out.reverse() return out