Con Sqlite, un comando "select..from" devuelve los resultados "salida", que imprime (en python):
>>print output
[(12.2817, 12.2817), (0, 0), (8.52, 8.52)]
Parece ser una lista de tuplas. Me gustaría convertir la "salida" en una matriz 1D simple (= lista en Python, supongo):
[12.2817, 12.2817, 0, 0, 8.52, 8.52]
o una matriz de 2x3:
12.2817 12.2817
0 0
8.52 8.52
para ser leído a través de "salida [i] [j]"
El comando aplanar no hace el trabajo para la primera opción, y no tengo idea de la segunda ... :)
¿Podrías darme una pista? Algo rápido sería genial ya que los datos reales son mucho más grandes (aquí hay solo un ejemplo simple).
[(12.2817, 12.2817), (0, 0), (8.52, 8.52)]
ya es una matriz de 3x2!? o me perdí algo?[item for sublist in output for item in sublist]
funciona perfectamente y tiene la ventaja de que sus tuplas internas también pueden ser listas; más generalmente, cualquier combinación de trabajos iterables internos y externosRespuestas:
Con mucho, la solución más rápida (y más corta) publicada:
list(sum(output, ()))
Aproximadamente un 50% más rápido que la
itertools
solución y aproximadamente un 70% más rápido que lamap
solución.fuente
list(output[0]+output[1]+output[2])
da el resultado deseado perolist(sum(output))
no. ¿Por qué? ¿Qué "magia" hace ()?sum(sequence[, start])
: sum agregastart
cuál es el valor predeterminado en0
lugar de comenzar desdesequence[0]
si existe y luego agregar el resto de los elementos. Lo siento por molestarte.sum
para concatenar secuencias, da como resultado un algoritmo de tiempo cuadrático. De hecho, ¡lasum
función se quejará si intenta hacer esto con cadenas!Enfoque de comprensión de listas que funciona con tipos Iterables y es más rápido que otros métodos que se muestran aquí.
flattened = [item for sublist in l for item in sublist]
l
es la lista para aplanar (llamadaoutput
en el caso del OP)pruebas timeit:
l = list(zip(range(99), range(99))) # list of tuples to flatten
Comprensión de listas
[item for sublist in l for item in sublist]
timeit resultado = 7,67 µs ± 129 ns por bucle
Método de extensión de lista ()
flattened = [] list(flattened.extend(item) for item in l)
timeit resultado = 11 µs ± 433 ns por bucle
suma()
list(sum(l, ()))
timeit resultado = 24,2 µs ± 269 ns por bucle
fuente
En Python 2.7, y todas las versiones de Python3, puede usar
itertools.chain
para aplanar una lista de iterables. O con la*
sintaxis o el método de clase.>>> t = [ (1,2), (3,4), (5,6) ] >>> t [(1, 2), (3, 4), (5, 6)] >>> import itertools >>> list(itertools.chain(*t)) [1, 2, 3, 4, 5, 6] >>> list(itertools.chain.from_iterable(t)) [1, 2, 3, 4, 5, 6]
fuente
Actualización : Aplanar usando extender pero sin comprensión y sin usar la lista como iterador (más rápido)
Después de verificar la siguiente respuesta a esto que proporcionó una solución más rápida a través de una comprensión de lista
dual for
, hice un pequeño ajuste y ahora funciona mejor, primero la ejecución de la lista (...) fue arrastrando un gran porcentaje de tiempo, luego cambiando una lista la comprensión de un bucle simple también se afeitó un poco más.La nueva solución es:
l = [] for row in output: l.extend(row)
Mayor:
Aplanamiento con mapa / extender:
l = [] list(map(l.extend, output))
Acoplamiento con comprensión de lista en lugar de mapa
l = [] list(l.extend(row) for row in output)
algún tiempo es para una nueva extensión y la mejora obtenida simplemente eliminando la lista (...) para [...]:
import timeit t = timeit.timeit o = "output=list(zip(range(1000000000), range(10000000))); l=[]" steps_ext = "for row in output: l.extend(row)" steps_ext_old = "list(l.extend(row) for row in output)" steps_ext_remove_list = "[l.extend(row) for row in output]" steps_com = "[item for sublist in output for item in sublist]" print("new extend: ", t(steps_ext, setup=o, number=10)) print("old extend w []: ", t(steps_ext_remove_list, setup=o, number=10)) print("comprehension: ", t(steps_com, setup=o, number=10,)) print("old extend: ", t(steps_ext_old, setup=o, number=10)) >>> new extend: 4.502427191007882 >>> old extend w []: 5.281140706967562 >>> comprehension: 5.54302118299529 >>> old extend: 6.840151469223201
fuente
itertools
cadena de uso :>>> import itertools >>> list(itertools.chain.from_iterable([(12.2817, 12.2817), (0, 0), (8.52, 8.52)])) [12.2817, 12.2817, 0, 0, 8.52, 8.52]
fuente
>>> flat_list = [] >>> nested_list = [(1, 2, 4), (0, 9)] >>> for a_tuple in nested_list: ... flat_list.extend(list(a_tuple)) ... >>> flat_list [1, 2, 4, 0, 9] >>>
podría pasar fácilmente de una lista de tuplas a una lista única como se muestra arriba.
fuente
O puede aplanar la lista de esta manera:
reduce(lambda x,y:x+y, map(list, output))
fuente
reduce(lambda x,y:x+y, output)
parece funcionar directamente convirtiendo a una tupla larga (que se puede convertir en una lista). ¿Por qué usarmap(list, output)
dentro de lareduce()
llamada? Tal vez esté más en línea con el hecho de que las tuplas son inmutables, las listas son mutables .Esto es para lo que
numpy
se hizo, tanto desde una perspectiva de estructura de datos como de velocidad.import numpy as np output = [(12.2817, 12.2817), (0, 0), (8.52, 8.52)] output_ary = np.array(output) # this is your matrix output_vec = output_ary.ravel() # this is your 1d-array
fuente
En caso de listas anidadas arbitrarias (por si acaso):
def flatten(lst): result = [] for element in lst: if hasattr(element, '__iter__'): result.extend(flatten(element)) else: result.append(element) return result >>> flatten(output) [12.2817, 12.2817, 0, 0, 8.52, 8.52]
fuente