tuplas - Fusionando/agregando listas en Python
tamaño de una lista python (8)
[sum (a) para un en zip (* array)]
Me gusta eso. Necesitaba algo relacionado para entrelazar objetos en una lista de elementos, se me ocurrió algo similar pero más conciso para listas de igual longitud:
sum(zip(*array),())
por ejemplo, entrelazando dos listas:
a = [1,2,3]
b = [''a'',''b'',''c'']
sum(zip(a,b),())
(1, ''a'', 2, ''b'', 3, ''c'')
Estoy bastante seguro de que debería haber una forma más pitonica de hacerlo, pero no puedo pensar en una: ¿cómo puedo fusionar una lista bidimensional en una lista unidimensional? Algo así como zip / map pero con más de dos iteradores.
Ejemplo - Tengo la siguiente lista:
array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
quiero tener
result = [12, 15, 18] # [1+4+7, 2+5+8, 3+6+9]
Hasta ahora, lo que se me ocurrió es:
def add_list(array):
number_items = len(array[0])
result = [0] * number_items
for index in range(number_items):
for line in array:
result[index] += line[index]
return result
Pero eso no se ve muy elegante / Pythonic para mí. Además de no verificar si todas las "líneas" en la matriz 2D son de la misma longitud, pueden agregarse entre sí, etc. ¿Cuál sería una mejor manera de hacerlo?
Estoy de acuerdo con las cinco campanas, pero también podrías usar Numpy, que es una implementación más pequeña (importación más rápida) y más genérica de cosas tipo array. (en realidad, es una dependencia de scipy). Estas son excelentes herramientas que, como se ha dicho, son ''imprescindibles'' si se trata de este tipo de manipulaciones.
Si estás haciendo mucho de este tipo de cosas, quieres aprender sobre scipy.
>>> import scipy
>>> sum(scipy.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]))
array([12, 15, 18])
Todos los tamaños de matriz se comprueban automáticamente. La suma se realiza en C puro, por lo que es muy rápido. scipy
matrices scipy
también son muy eficientes en la memoria.
El inconveniente es que dependes de un módulo de terceros bastante complejo. Pero esa es una muy buena compensación para muchos propósitos.
Simplemente puede hacer esto:
print [sum(x) for x in zip(*array)]
Si desea iterar a través de las listas de esta manera, puede usar la chain
del módulo itertools
:
from itertools import chain
for x in array.chain.from_iterable(zip(*array)):
print x
# prints 1, 4, 7, 2, 5, 8, ...
Tarde en el juego, y no es una respuesta tan buena como algunas de las otras, pero pensé que era linda:
map(lambda *x:sum(x),*array)
es una lástima que la sum(1,2,3)
no funcione. Si lo hiciera, podríamos eliminar la lambda
tonta allí, pero supongo que eso dificultaría discernir cuál (si es que tiene alguno) de los elementos es el "inicio" de la suma. Tendría que cambiar eso a una palabra clave única discusión que rompería muchas secuencias de comandos ... Oh bien. Supongo que solo viviremos con lambda
.
Una forma alternativa:
map(sum, zip(*array))
[sum (value) for value in zip (* array)] es bastante estándar.
Esto puede ayudarte a entenderlo:
In [1]: array=[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
In [2]: array
Out[2]: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
In [3]: *array
------------------------------------------------------------
File "<ipython console>", line 1
*array
^
<type ''exceptions.SyntaxError''>: invalid syntax
La estrella única no es un operador en sí mismo. Desenreda los elementos de la matriz en argumentos en llamadas a funciones.
In [4]: zip(*array)
Out[4]: [(1, 4, 7), (2, 5, 8), (3, 6, 9)]
zip () es una función incorporada
In [5]: zip(*array)[0]
Out[5]: (1, 4, 7)
cada elemento de la lista devuelta por zip es un conjunto de números que desea.
In [6]: sum(zip(*array)[0])
Out[6]: 12
In [7]: [sum(values) for values in zip(*array)]
Out[7]: [12, 15, 18]
[sum(a) for a in zip(*array)]