2012-04-22 16 views
10
# 2x3 dimensional list 
multidim_list = [ 
        [1,2,3], 
        [4,5,6],  
       ] 
# 2x3x2 dimensional list 
multidim_list2 = [ 
        [ 
        [1,2,3], 
        [4,5,6], 
        ], 
        [ 
        [7,8,9], 
        [10,11,12], 
        ] 
       ] 

def multiply_list(list): 
    ... 

Me gustaría implementar una función que multiplique por dos todos los elementos de la lista. Sin embargo, mi problema es que las listas pueden tener diferentes dimensiones.Python: Iterar listas con diferente cantidad de dimensiones, ¿hay alguna manera genérica?

¿Hay una manera general de iterar/iterar la lista multidimensional y, por ejemplo, multiplicar cada valor por dos?

EDIT1: Gracias por las respuestas rápidas. Para este caso, no quiero usar numpy. La recursión parece buena, y ni siquiera necesita hacer una copia de la lista, que en realidad podría ser bastante grande.

Respuesta

15

La recursividad es su amigo:

from collections import MutableSequence 
def multiply(list_): 
    for index, item in enumerate(list_): 
     if isinstance(item, MutableSequence): 
      multiply(item) 
     else: 
      list_[index] *= 2 

Se podía hacer isinstance(item, list) en lugar de isinstance(item, MutableSequence), pero la última forma es más Futureproof y genérica. Ver the glossary para una breve explicación.

+0

Esto es lo que quería. Ha pasado mucho tiempo desde que utilicé la recursión, casi la olvido. Y no quería usar numpy para este caso. – JoonasS

+0

"... también es la forma en que se realizan tales comprobaciones en las bibliotecas de Python". Solo por curiosidad: ¿qué bibliotecas de Python tienes en mente aquí? –

+0

@Sven reventado. Buscando las "baterías" no he encontrado tal control. Lo más cerca que he llegado es que shutil usa 'isinstance (function, collections.Callable)'. Sin embargo, hay toneladas de verificaciones 'isinstance (x, list)'. Creo que donde sea que una función o clase incorporada necesite verificar el tipo de sus argumentos (por ejemplo, es una lista o un dict), haría esto usando el ABC en 'colecciones', para que los usuarios puedan sustituir la' lista 'objetar con una subclase' MutableSequence' y todavía hacer que funcione. Honestamente, pensé que esta era una gran razón por la que presentaron el abecedario en primer lugar. Editaré mi respuesta. –

3

numpy arreglos hacen eso fuera de la caja.

8

Usted puede hacer uso de numpy:

import numpy as np 

arr_1 = np.array(multidim_list) 
arr_2 = np.array(multidim_list2) 

Resultado:

>>> arr_1*2 
array([[ 2, 4, 6], 
     [ 8, 10, 12]]) 
>>> arr_2*2 
array([[[ 2, 4, 6], 
     [ 8, 10, 12]], 

     [[14, 16, 18], 
     [20, 22, 24]]]) 
Cuestiones relacionadas