es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Mapeo perezoso entre enteros y permutaciones de matrices sin generar todas las permutaciones.

Quiero generar una correspondencia entre un conjunto de matrices de enteros y valores enteros en Python, por ejemplo, para n=2 (tamaño de la matriz) y m=2 (rango de elementos de la matriz), quiero tener:

{
   0: [0, 0, 0],
   1: [0, 0, 1],
   2: [0, 1, 1],
   3: [1, 0, 0],
   ...
   7: [1, 1, 1]
}

Una forma de hacer esto es utilizar itertools.product y hacer lo siguiente:

from itertools import product
import numpy as np
n = 2
m = 3
a = list(product(np.arange(n), repeat=3))
a = list(map(lambda l: list(l), a))
b = dict(zip(np.arange(len(a)), a))

Y b será:

{0: [0, 0, 0], 1: [0, 0, 1], 2: [0, 1, 0], 3: [0, 1, 1], 4: [1, 0, 0], 5: [1, 0, 1], 6: [1, 1, 0], 7: [1, 1, 1]}

Y puedo obtener la correspondencia mencionada, por ejemplo:

>>> b[1]
[0, 0, 1]

Sin embargo, en mi caso, n=8 y m=16, ¡y almacenar un diccionario de este tamaño (8**16 entradas!) ocupará más de 100 Gb! Quiero saber si existe una forma “perezosa” de generar cada índice de b cada vez que quiero acceder a él sin generar el diccionario completo.

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Sí, puedes utilizar una función generadora para generar perezosamente cada índice del diccionario b según sea necesario. Aquí hay un ejemplo de una función generadora que logra esto:

    def get_array_map(n, m):
        for i, valores in enumerate(product(range(m), repeat=n)):
            yield i, list(valores)
    

    Utilizarías esta función de la siguiente manera:

    n, m = 8, 16
    b = dict(get_array_map(n, m))
    

    Ahora puedes acceder a arrays individuales en b utilizando la misma sintaxis que antes, pero get_array_map() solo generará los arrays cuando los accedas:

    >>> b[1]
    [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    

    De esta manera, no necesitas almacenar todo el diccionario en memoria de una sola vez. Ten en cuenta que generar todo el diccionario en este caso requeriría más de 100 GB de memoria, mientras que generar cada entrada según se necesiten solo requerirá la memoria para almacenar un array a la vez.

Comments are closed.