tutorial for espaƱol else comprehension python list-comprehension

for - Aplanando una lista poco profunda en Python



python list comprehension tutorial (23)

¡Casi lo tienes! La forma de hacer una lista de comprensión anidada es colocar las sentencias for en el mismo orden en el que se incluirían en las anotaciones anidadas regulares.

Así, este

for inner_list in outer_list: for item in inner_list: ...

corresponde a

[... for inner_list in outer_list for item in inner_list]

Entonces quieres

[image for menuitem in list_of_menuitems for image in menuitem]

Esta pregunta ya tiene una respuesta aquí:

¿Existe una forma sencilla de aplanar una lista de iterables con una lista de comprensión, o si falla, cuál consideraría que es la mejor manera de aplanar una lista poco profunda como esta, equilibrando el rendimiento y la legibilidad?

Traté de aplanar una lista de este tipo con una comprensión de lista anidada, como esta:

[image for image in menuitem for menuitem in list_of_menuitems]

Pero me meto en problemas con la variedad NameError allí, porque el name ''menuitem'' is not defined . Después de buscar en Google y mirar a mi alrededor en Stack Overflow, obtuve los resultados deseados con una declaración de reduce :

reduce(list.__add__, map(lambda x: list(x), list_of_menuitems))

Pero este método es bastante ilegible porque necesito que esa list(x) llame allí porque x es un objeto Django QuerySet .

Conclusión :

Gracias a todos los que contribuyeron a esta pregunta. Aquí hay un resumen de lo que aprendí. También estoy haciendo de esto una wiki comunitaria en caso de que otros quieran agregar o corregir estas observaciones.

Mi declaración de reducción original es redundante y se escribe mejor de esta manera:

>>> reduce(list.__add__, (list(mi) for mi in list_of_menuitems))

Esta es la sintaxis correcta para una lista de comprensión anidada (¡Brillante resumen dF !):

>>> [image for mi in list_of_menuitems for image in mi]

Pero ninguno de estos métodos es tan eficiente como usar itertools.chain :

>>> from itertools import chain >>> list(chain(*list_of_menuitems))

Y como observa @cdleary, es probablemente mejor estilo para evitar * la magia del operador utilizando chain.from_iterable manera:

>>> chain = itertools.chain.from_iterable([[1,2],[3],[5,89],[],[6]]) >>> print(list(chain)) >>> [1, 2, 3, 5, 89, 6]


Aquí está la solución correcta usando la lista de comprensión (están al revés en la pregunta):

>>> join = lambda it: (y for x in it for y in x) >>> list(join([[1,2],[3,4,5],[]])) [1, 2, 3, 4, 5]

En tu caso sería

[image for menuitem in list_of_menuitems for image in menuitem.image_set.all()]

o podrías usar join y decir

join(menuitem.image_set.all() for menuitem in list_of_menuitems)

En cualquier caso, el gotcha fue la anidación de los bucles for .


Aquí hay una versión que funciona para múltiples niveles de lista usando collectons.Iterable :

import collections def flatten(o): result = [] for i in o: if isinstance(i, collections.Iterable): result.extend(flatten(i)) else: result.append(i) return result


De la parte superior de mi cabeza, puedes eliminar la lambda:

reduce(list.__add__, map(list, [mi.image_set.all() for mi in list_of_menuitems]))

O incluso elimine el mapa, ya que ya tiene una lista comp:

reduce(list.__add__, [list(mi.image_set.all()) for mi in list_of_menuitems])

También puedes expresar esto como una suma de listas:

sum([list(mi.image_set.all()) for mi in list_of_menuitems], [])


Desde mi experiencia, la forma más eficiente de aplanar una lista de listas es:

flat_list = [] map(flat_list.extend, list_of_list)

Algunas comparaciones de tiempo con los otros métodos propuestos:

list_of_list = [range(10)]*1000 %timeit flat_list=[]; map(flat_list.extend, list_of_list) #10000 loops, best of 3: 119 µs per loop %timeit flat_list=list(itertools.chain.from_iterable(list_of_list)) #1000 loops, best of 3: 210 µs per loop %timeit flat_list=[i for sublist in list_of_list for i in sublist] #1000 loops, best of 3: 525 µs per loop %timeit flat_list=reduce(list.__add__,list_of_list) #100 loops, best of 3: 18.1 ms per loop

Ahora, la ganancia de eficiencia aparece mejor cuando se procesan listas más largas:

list_of_list = [range(1000)]*10 %timeit flat_list=[]; map(flat_list.extend, list_of_list) #10000 loops, best of 3: 60.7 µs per loop %timeit flat_list=list(itertools.chain.from_iterable(list_of_list)) #10000 loops, best of 3: 176 µs per loop

Y este método también funciona con cualquier objeto iterativo:

class SquaredRange(object): def __init__(self, n): self.range = range(n) def __iter__(self): for i in self.range: yield i**2 list_of_list = [SquaredRange(5)]*3 flat_list = [] map(flat_list.extend, list_of_list) print flat_list #[0, 1, 4, 9, 16, 0, 1, 4, 9, 16, 0, 1, 4, 9, 16]


En Python 3.4 podrás hacer:

[*innerlist for innerlist in outer_list]


En Python 2.6, usando chain.from_iterable() :

>>> from itertools import chain >>> list(chain.from_iterable(mi.image_set.all() for mi in h.get_image_menu()))

Se evita la creación de listas intermedias.


Esta solución funciona para profundidades de anidación arbitrarias, no solo la profundidad de "listas de listas" a la que algunas (¿todas?) De las otras soluciones se limitan a:

def flatten(x): result = [] for el in x: if hasattr(el, "__iter__") and not isinstance(el, basestring): result.extend(flatten(el)) else: result.append(el) return result

Es la recursión que permite el anidamiento de profundidad arbitrario, hasta que alcance la profundidad máxima de recursión, por supuesto ...


Esta versión es un generador. Débilelo si quieres una lista.

def list_or_tuple(l): return isinstance(l,(list,tuple)) ## predicate will select the container to be flattened ## write your own as required ## this one flattens every list/tuple def flatten(seq,predicate=list_or_tuple): ## recursive generator for i in seq: if predicate(seq): for j in flatten(i): yield j else: yield i

Puede agregar un predicado, si desea aplanar aquellos que satisfacen una condición

Tomado del libro de cocina de Python


La forma más fácil de lograr esto en Python 2 o 3 es usar la biblioteca de morph usando pip install morph .

El código es:

import morph list = [[1,2],[3],[5,89],[],[6]] flattened_list = morph.flatten(list) # returns [1, 2, 3, 5, 89, 6]


Parece que hay una confusión con operator.add ! Cuando agrega dos listas juntas, el término correcto para eso es concat , no add. operator.concat es lo que necesitas usar.

Si estás pensando en funcional, es tan fácil como esto:

>>> list2d = ((1,2,3),(4,5,6), (7,), (8,9)) >>> reduce(operator.concat, list2d) (1, 2, 3, 4, 5, 6, 7, 8, 9)

Verás reduce el tipo de secuencia, de modo que cuando suministras una tupla, recuperas una tupla. vamos a intentar con una lista ::

>>> list2d = [[1,2,3],[4,5,6], [7], [8,9]] >>> reduce(operator.concat, list2d) [1, 2, 3, 4, 5, 6, 7, 8, 9]

Ajá, vuelves una lista.

¿Qué tal el rendimiento ::

>>> list2d = [[1,2,3],[4,5,6], [7], [8,9]] >>> %timeit list(itertools.chain.from_iterable(list2d)) 1000000 loops, best of 3: 1.36 µs per loop

from_iterable es bastante rápido! Pero no hay comparación para reducir con concat.

>>> list2d = ((1,2,3),(4,5,6), (7,), (8,9)) >>> %timeit reduce(operator.concat, list2d) 1000000 loops, best of 3: 492 ns per loop



Qué pasa:

from operator import add reduce(add, map(lambda x: list(x.image_set.all()), [mi for mi in list_of_menuitems]))

Sin embargo, Guido recomienda no realizar demasiado en una sola línea de código, ya que reduce la legibilidad. La ganancia de rendimiento es mínima, si la hay, al realizar lo que desea en una sola línea en lugar de varias líneas.


Resultados de rendimiento. Revisado.

import itertools def itertools_flatten( aList ): return list( itertools.chain(*aList) ) from operator import add def reduce_flatten1( aList ): return reduce(add, map(lambda x: list(x), [mi for mi in aList])) def reduce_flatten2( aList ): return reduce(list.__add__, map(list, aList)) def comprehension_flatten( aList ): return list(y for x in aList for y in x)

Aplané una lista de 2 niveles de 30 artículos 1000 veces

itertools_flatten 0.00554 comprehension_flatten 0.00815 reduce_flatten2 0.01103 reduce_flatten1 0.01404

Reducir es siempre una mala elección.


Si cada elemento de la lista es una cadena (y las cadenas dentro de esas cadenas usan "" en lugar de ''''), puede usar expresiones regulares ( re módulo)

>>> flattener = re.compile("/'.*?/'") >>> flattener <_sre.SRE_Pattern object at 0x10d439ca8> >>> stred = str(in_list) >>> outed = flattener.findall(stred)

El código anterior convierte in_list en una cadena, usa la expresión regular para encontrar todas las subcadenas entre comillas (es decir, cada elemento de la lista) y las escupe como una lista.


Si está buscando un simple, integrado, de una sola línea, puede usar:

a = [[1, 2, 3], [4, 5, 6] b = [i[x] for i in a for x in range(len(i))] print b

devoluciones

[1, 2, 3, 4, 5, 6]


Si solo está buscando iterar sobre una versión aplanada de la estructura de datos y no necesita una secuencia indexable, considere itertools.chain y compañía .

>>> list_of_menuitems = [[''image00'', ''image01''], [''image10''], []] >>> import itertools >>> chain = itertools.chain(*list_of_menuitems) >>> print(list(chain)) [''image00'', ''image01'', ''image10'']

Funcionará en cualquier cosa que sea iterable, que debería incluir los QuerySet iterables de QuerySet , que parece que estás usando en la pregunta.

Editar: De todos modos, esto es probablemente tan bueno como una reducción, porque reducir tendrá la misma sobrecarga al copiar los elementos en la lista que se está extendiendo. chain solo incurrirá en esta (misma) sobrecarga si ejecuta la list(chain) al final.

Meta-Edición: en realidad, es menos costoso que la solución propuesta de la pregunta, porque tira las listas temporales que crea cuando extiende el original con el temporal.

Edición: como dice JF Sebastian itertools.chain.from_iterable evita el desempaquetado y debes usar eso para evitar la magia * , pero la aplicación timeit muestra una diferencia de rendimiento insignificante.


Si tiene que aplanar una lista más complicada con elementos no iterables o con una profundidad superior a 2, puede utilizar la siguiente función:

def flat_list(list_to_flat): if not isinstance(list_to_flat, list): yield list_to_flat else: for item in list_to_flat: yield from flat_list(item)

Devolverá el objeto generador que puede convertir a la lista con la función list() . Tenga en cuenta que el yield from sintaxis disponible de python3.3 pero en su lugar puede usar iteración explícita.
Ejemplo:

>>> a = [1, [2, 3], [1, [2, 3, [1, [2, 3]]]]] >>> print(list(flat_list(a))) [1, 2, 3, 1, 2, 3, 1, 2, 3]


Una alternativa simple es utilizar concatenate de numpy pero convierte los contenidos a flotar:

import numpy as np print np.concatenate([[1,2],[3],[5,89],[],[6]]) # array([ 1., 2., 3., 5., 89., 6.]) print list(np.concatenate([[1,2],[3],[5,89],[],[6]])) # [ 1., 2., 3., 5., 89., 6.]


has intentado aplanar? Desde matplotlib.cbook.flatten (seq, scalarp =) ?

l=[[1,2,3],[4,5,6], [7], [8,9]]*33 run("list(flatten(l))") 3732 function calls (3303 primitive calls) in 0.007 seconds Ordered by: standard name ncalls tottime percall cumtime percall filename:lineno(function) 1 0.000 0.000 0.007 0.007 <string>:1(<module>) 429 0.001 0.000 0.001 0.000 cbook.py:475(iterable) 429 0.002 0.000 0.003 0.000 cbook.py:484(is_string_like) 429 0.002 0.000 0.006 0.000 cbook.py:565(is_scalar_or_string) 727/298 0.001 0.000 0.007 0.000 cbook.py:605(flatten) 429 0.000 0.000 0.001 0.000 core.py:5641(isMaskedArray) 858 0.001 0.000 0.001 0.000 {isinstance} 429 0.000 0.000 0.000 0.000 {iter} 1 0.000 0.000 0.000 0.000 {method ''disable'' of ''_lsprof.Profiler'' objects} l=[[1,2,3],[4,5,6], [7], [8,9]]*66 run("list(flatten(l))") 7461 function calls (6603 primitive calls) in 0.007 seconds Ordered by: standard name ncalls tottime percall cumtime percall filename:lineno(function) 1 0.000 0.000 0.007 0.007 <string>:1(<module>) 858 0.001 0.000 0.001 0.000 cbook.py:475(iterable) 858 0.002 0.000 0.003 0.000 cbook.py:484(is_string_like) 858 0.002 0.000 0.006 0.000 cbook.py:565(is_scalar_or_string) 1453/595 0.001 0.000 0.007 0.000 cbook.py:605(flatten) 858 0.000 0.000 0.001 0.000 core.py:5641(isMaskedArray) 1716 0.001 0.000 0.001 0.000 {isinstance} 858 0.000 0.000 0.000 0.000 {iter} 1 0.000 0.000 0.000 0.000 {method ''disable'' of ''_lsprof.Profiler'' objects} l=[[1,2,3],[4,5,6], [7], [8,9]]*99 run("list(flatten(l))") 11190 function calls (9903 primitive calls) in 0.010 seconds Ordered by: standard name ncalls tottime percall cumtime percall filename:lineno(function) 1 0.000 0.000 0.010 0.010 <string>:1(<module>) 1287 0.002 0.000 0.002 0.000 cbook.py:475(iterable) 1287 0.003 0.000 0.004 0.000 cbook.py:484(is_string_like) 1287 0.002 0.000 0.009 0.000 cbook.py:565(is_scalar_or_string) 2179/892 0.001 0.000 0.010 0.000 cbook.py:605(flatten) 1287 0.001 0.000 0.001 0.000 core.py:5641(isMaskedArray) 2574 0.001 0.000 0.001 0.000 {isinstance} 1287 0.000 0.000 0.000 0.000 {iter} 1 0.000 0.000 0.000 0.000 {method ''disable'' of ''_lsprof.Profiler'' objects} l=[[1,2,3],[4,5,6], [7], [8,9]]*132 run("list(flatten(l))") 14919 function calls (13203 primitive calls) in 0.013 seconds Ordered by: standard name ncalls tottime percall cumtime percall filename:lineno(function) 1 0.000 0.000 0.013 0.013 <string>:1(<module>) 1716 0.002 0.000 0.002 0.000 cbook.py:475(iterable) 1716 0.004 0.000 0.006 0.000 cbook.py:484(is_string_like) 1716 0.003 0.000 0.011 0.000 cbook.py:565(is_scalar_or_string) 2905/1189 0.002 0.000 0.013 0.000 cbook.py:605(flatten) 1716 0.001 0.000 0.001 0.000 core.py:5641(isMaskedArray) 3432 0.001 0.000 0.001 0.000 {isinstance} 1716 0.001 0.000 0.001 0.000 {iter} 1 0.000 0.000 0.000 0.000 {method ''disable'' of ''_lsprof.Profiler''

ACTUALIZACIÓN Lo que me dio otra idea:

l=[[1,2,3],[4,5,6], [7], [8,9]]*33 run("flattenlist(l)") 564 function calls (432 primitive calls) in 0.000 seconds Ordered by: standard name ncalls tottime percall cumtime percall filename:lineno(function) 133/1 0.000 0.000 0.000 0.000 <ipython-input-55-39b139bad497>:4(flattenlist) 1 0.000 0.000 0.000 0.000 <string>:1(<module>) 429 0.000 0.000 0.000 0.000 {isinstance} 1 0.000 0.000 0.000 0.000 {method ''disable'' of ''_lsprof.Profiler'' objects} l=[[1,2,3],[4,5,6], [7], [8,9]]*66 run("flattenlist(l)") 1125 function calls (861 primitive calls) in 0.001 seconds Ordered by: standard name ncalls tottime percall cumtime percall filename:lineno(function) 265/1 0.001 0.000 0.001 0.001 <ipython-input-55-39b139bad497>:4(flattenlist) 1 0.000 0.000 0.001 0.001 <string>:1(<module>) 858 0.000 0.000 0.000 0.000 {isinstance} 1 0.000 0.000 0.000 0.000 {method ''disable'' of ''_lsprof.Profiler'' objects} l=[[1,2,3],[4,5,6], [7], [8,9]]*99 run("flattenlist(l)") 1686 function calls (1290 primitive calls) in 0.001 seconds Ordered by: standard name ncalls tottime percall cumtime percall filename:lineno(function) 397/1 0.001 0.000 0.001 0.001 <ipython-input-55-39b139bad497>:4(flattenlist) 1 0.000 0.000 0.001 0.001 <string>:1(<module>) 1287 0.000 0.000 0.000 0.000 {isinstance} 1 0.000 0.000 0.000 0.000 {method ''disable'' of ''_lsprof.Profiler'' objects} l=[[1,2,3],[4,5,6], [7], [8,9]]*132 run("flattenlist(l)") 2247 function calls (1719 primitive calls) in 0.002 seconds Ordered by: standard name ncalls tottime percall cumtime percall filename:lineno(function) 529/1 0.001 0.000 0.002 0.002 <ipython-input-55-39b139bad497>:4(flattenlist) 1 0.000 0.000 0.002 0.002 <string>:1(<module>) 1716 0.001 0.000 0.001 0.000 {isinstance} 1 0.000 0.000 0.000 0.000 {method ''disable'' of ''_lsprof.Profiler'' objects} l=[[1,2,3],[4,5,6], [7], [8,9]]*1320 run("flattenlist(l)") 22443 function calls (17163 primitive calls) in 0.016 seconds Ordered by: standard name ncalls tottime percall cumtime percall filename:lineno(function) 5281/1 0.011 0.000 0.016 0.016 <ipython-input-55-39b139bad497>:4(flattenlist) 1 0.000 0.000 0.016 0.016 <string>:1(<module>) 17160 0.005 0.000 0.005 0.000 {isinstance} 1 0.000 0.000 0.000 0.000 {method ''disable'' of ''_lsprof.Profiler'' objects}

Entonces, para probar qué tan efectivo es cuando la recursividad se vuelve más profunda: ¿Cuánto más profundo?

l=[[1,2,3],[4,5,6], [7], [8,9]]*1320 new=[l]*33 run("flattenlist(new)") 740589 function calls (566316 primitive calls) in 0.418 seconds Ordered by: standard name ncalls tottime percall cumtime percall filename:lineno(function) 174274/1 0.281 0.000 0.417 0.417 <ipython-input-55-39b139bad497>:4(flattenlist) 1 0.001 0.001 0.418 0.418 <string>:1(<module>) 566313 0.136 0.000 0.136 0.000 {isinstance} 1 0.000 0.000 0.000 0.000 {method ''disable'' of ''_lsprof.Profiler'' objects} new=[l]*66 run("flattenlist(new)") 1481175 function calls (1132629 primitive calls) in 0.809 seconds Ordered by: standard name ncalls tottime percall cumtime percall filename:lineno(function) 348547/1 0.542 0.000 0.807 0.807 <ipython-input-55-39b139bad497>:4(flattenlist) 1 0.002 0.002 0.809 0.809 <string>:1(<module>) 1132626 0.266 0.000 0.266 0.000 {isinstance} 1 0.000 0.000 0.000 0.000 {method ''disable'' of ''_lsprof.Profiler'' objects} new=[l]*99 run("flattenlist(new)") 2221761 function calls (1698942 primitive calls) in 1.211 seconds Ordered by: standard name ncalls tottime percall cumtime percall filename:lineno(function) 522820/1 0.815 0.000 1.208 1.208 <ipython-input-55-39b139bad497>:4(flattenlist) 1 0.002 0.002 1.211 1.211 <string>:1(<module>) 1698939 0.393 0.000 0.393 0.000 {isinstance} 1 0.000 0.000 0.000 0.000 {method ''disable'' of ''_lsprof.Profiler'' objects} new=[l]*132 run("flattenlist(new)") 2962347 function calls (2265255 primitive calls) in 1.630 seconds Ordered by: standard name ncalls tottime percall cumtime percall filename:lineno(function) 697093/1 1.091 0.000 1.627 1.627 <ipython-input-55-39b139bad497>:4(flattenlist) 1 0.003 0.003 1.630 1.630 <string>:1(<module>) 2265252 0.536 0.000 0.536 0.000 {isinstance} 1 0.000 0.000 0.000 0.000 {method ''disable'' of ''_lsprof.Profiler'' objects} new=[l]*1320 run("flattenlist(new)") 29623443 function calls (22652523 primitive calls) in 16.103 seconds Ordered by: standard name ncalls tottime percall cumtime percall filename:lineno(function) 6970921/1 10.842 0.000 16.069 16.069 <ipython-input-55-39b139bad497>:4(flattenlist) 1 0.034 0.034 16.103 16.103 <string>:1(<module>) 22652520 5.227 0.000 5.227 0.000 {isinstance} 1 0.000 0.000 0.000 0.000 {method ''disable'' of ''_lsprof.Profiler'' objects}

Apostaré a "flattenlist". Usaré esto en lugar de matploblib durante mucho tiempo, a menos que quiera un generador de rendimiento y un resultado rápido, ya que "flatten" se utiliza en matploblib.cbook

Esto, es rápido.

  • Y aquí está el código.

:

typ=(list,tuple) def flattenlist(d): thelist = [] for x in d: if not isinstance(x,typ): thelist += [x] else: thelist += flattenlist(x) return thelist


@S.Lott : Me inspiraste para escribir una aplicación de timeit.

Pensé que también variaría en función del número de particiones (número de iteradores dentro de la lista de contenedores); su comentario no mencionó cuántas particiones había de los treinta elementos. Esta gráfica está aplanando mil elementos en cada ejecución, con un número variable de particiones. Los artículos se distribuyen uniformemente entre las particiones.

Código (Python 2.6):

#!/usr/bin/env python2.6 """Usage: %prog item_count""" from __future__ import print_function import collections import itertools import operator from timeit import Timer import sys import matplotlib.pyplot as pyplot def itertools_flatten(iter_lst): return list(itertools.chain(*iter_lst)) def itertools_iterable_flatten(iter_iter): return list(itertools.chain.from_iterable(iter_iter)) def reduce_flatten(iter_lst): return reduce(operator.add, map(list, iter_lst)) def reduce_lambda_flatten(iter_lst): return reduce(operator.add, map(lambda x: list(x), [i for i in iter_lst])) def comprehension_flatten(iter_lst): return list(item for iter_ in iter_lst for item in iter_) METHODS = [''itertools'', ''itertools_iterable'', ''reduce'', ''reduce_lambda'', ''comprehension''] def _time_test_assert(iter_lst): """Make sure all methods produce an equivalent value. :raise AssertionError: On any non-equivalent value.""" callables = (globals()[method + ''_flatten''] for method in METHODS) results = [callable(iter_lst) for callable in callables] if not all(result == results[0] for result in results[1:]): raise AssertionError def time_test(partition_count, item_count_per_partition, test_count=10000): """Run flatten methods on a list of :param:`partition_count` iterables. Normalize results over :param:`test_count` runs. :return: Mapping from method to (normalized) microseconds per pass. """ iter_lst = [[dict()] * item_count_per_partition] * partition_count print(''Partition count: '', partition_count) print(''Items per partition:'', item_count_per_partition) _time_test_assert(iter_lst) test_str = ''flatten(%r)'' % iter_lst result_by_method = {} for method in METHODS: setup_str = ''from test import %s_flatten as flatten'' % method t = Timer(test_str, setup_str) per_pass = test_count * t.timeit(number=test_count) / test_count print(''%20s: %.2f usec/pass'' % (method, per_pass)) result_by_method[method] = per_pass return result_by_method if __name__ == ''__main__'': if len(sys.argv) != 2: raise ValueError(''Need a number of items to flatten'') item_count = int(sys.argv[1]) partition_counts = [] pass_times_by_method = collections.defaultdict(list) for partition_count in xrange(1, item_count): if item_count % partition_count != 0: continue items_per_partition = item_count / partition_count result_by_method = time_test(partition_count, items_per_partition) partition_counts.append(partition_count) for method, result in result_by_method.iteritems(): pass_times_by_method[method].append(result) for method, pass_times in pass_times_by_method.iteritems(): pyplot.plot(partition_counts, pass_times, label=method) pyplot.legend() pyplot.title(''Flattening Comparison for %d Items'' % item_count) pyplot.xlabel(''Number of Partitions'') pyplot.ylabel(''Microseconds'') pyplot.show()

Editar: Decidió hacerlo wiki de la comunidad.

Nota: los METHODS probablemente deberían acumularse con un decorador, pero creo que sería más fácil para las personas leer de esta manera.


sum(list of lists, []) lo aplanaría.

l = [[''image00'', ''image01''], [''image10''], []] print sum(l,[]) # prints [''image00'', ''image01'', ''image10'']


def flatten(items): for i in items: if hasattr(i, ''__iter__''): for m in flatten(i): yield m else: yield i

Prueba:

print list(flatten2([1.0, 2, ''a'', (4,), ((6,), (8,)), (((8,),(9,)), ((12,),(10)))]))